[Closed] sort array problem
time:0.031s memory:17700L
clearListener()
speresArr = for i=1 to 200 collect (sphere radius:(random 4 10) pos:(random [-100.0,-100.0,-100.0] [100.0,100.0,100.0]))
tstart = timestamp()
mstart = heapfree
handleArr = sort (for i = 1 to 200 collect getHandleByAnim speresArr[i])
sphereNames = for i in handleArr collect (getAnimByHandle i).name
format "time:% memory:%
" (((timestamp()-tstart)/1000.0) as string + "s") (mstart - heapfree)
--print sphereNames
time:0.172s memory:135060L
this method hard to perse,just for comparison.
clearListener()
tstart = timestamp()
mstart = heapfree
for i = 1 to 200 do
(
sphere radius:(random 4 10) \
pos:(random [-100,-100,-100] [100,100,100]) \
name:("Sphere" + (formattedprint i format:"03i"))
)
format "time:% memory:%
" (((timestamp()-tstart)/1000.0) as string + "s") (mstart - heapfree)
--sphereNames=for i in objects collect i.name
--print sphereNames
1)time:0.031s memory:44740L
2)time:0.016s memory:1148L
clearListener()
fn splitNumeratedName name =
(
string = trimright name "0123456789"
number = substring name (string.count+1) -1
#(string, number)
)
fn naturalSort arr1 arr2 =
(
if (act = stricmp arr1[1] arr2[1]) != 0 then act else (arr1[2] as integer - arr2[2] as integer)
)
--test
for i=1 to 200 do (sphere radius:(random 4 10) pos:(random [-100.0,-100.0,-100.0] [100.0,100.0,100.0]))
--1)
sphereNames=for i in objects collect (splitNumeratedName i.name )
tstart = timestamp()
mstart = heapfree
--2)
--sphereNames=for i in objects collect (splitNumeratedName i.name )
qsort sphereNames naturalSort
format "time:% memory:%
" (((timestamp()-tstart)/1000.0) as string + "s") (mstart - heapfree)
--print sphereNames
This is not my method but slightly modifierd verion of original Denis code.
My first methid will only help you only when you want to sort newly created nodes.
1.Mscript):time:0.031s memory:334060L
clearListener()
fn naturalSort name1 name2 =
(
base1 = trimright name1 "0123456789"
base2 = trimright name2 "0123456789"
if (act = stricmp base1 base2) != 0 then (act) else
(
id1 = substring name1 (base1.count+1) -1
id2 = substring name2 (base2.count+1) -1
id1 as integer - id2 as integer
)
)
--test
for i=1 to 200 do (sphere radius:(random 4 10) pos:(random [-100.0,-100.0,-100.0] [100.0,100.0,100.0]))
sphereNames=for i in objects collect i.name
tstart = timestamp()
mstart = heapfree
qsort sphereNames naturalSort
format "time:% memory:%
" (((timestamp()-tstart)/1000.0) as string + "s") (mstart - heapfree)
--print sphereNames
2.net): time:0.016s memory:1968L
clearListener()
fn makeIComparersAssembly =
(
source = ""
source += "using System;
"
source += "using System.Runtime.InteropServices;
"
source += "using System.Collections;
"
source += "namespace IComparers
"
source += "{
"
source += " public sealed class StringLogicalComparer: IComparer
"
source += " {
"
source += " [DllImport(\"shlwapi.dll\", CharSet = CharSet.Unicode, ExactSpelling = true)]
"
source += " static extern int StrCmpLogicalW(String x, String y);
"
source += " public int Compare(object x, object y)
"
source += " {
"
source += " return StrCmpLogicalW((String)x, (String)y);
"
source += " }
"
source += " }
"
source += "}
"
csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.GenerateInMemory = on
compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
compilerResults.CompiledAssembly
)
global StringLogicalComparer = (makeIComparersAssembly()).createInstance "IComparers.StringLogicalComparer"
--test
for i=1 to 200 do (sphere radius:(random 4 10) pos:(random [-100.0,-100.0,-100.0] [100.0,100.0,100.0]))
sphereNames=for i in objects collect i.name
tstart = timestamp()
mstart = heapfree
a = dotnet.valuetodotnetobject sphereNames (dotnetclass "System.String[]")
a.Sort a StringLogicalComparer
format "time:% memory:%
" (((timestamp()-tstart)/1000.0) as string + "s") (mstart - heapfree)
--print (a.Clone())
If this information is intended to be a reference for other developers (as you stated), you might want to review it as it is partially inaccurate.
#1. I’ve not provided a sorting algorithm.
#2. You are comparing sorting algorithms times with nodes creation times.
#3. If you have #(“A01”, “A100”) it would be better to have either #(“A001”, “A100”) or #(“A1”, “A100”).
If you decide to use #(“A001”, “A100”) then you could use some of the code mentioned earlier.
If you decide to use #(“A1”, “A100”) then Denis solution is probably the best you can do (although for this very specific task there might be some faster way of doing it ;))
calm down… i’m absolutely agree with you that this particular problem was happened because of not well organized node name increment. but it’s a common problem. see the windows. it sorts files alphabetical way instead of natural.
(but i’m absolutely agreed with you – if you expect to have 3N nodes of the same kind, you have to preserve three digits for their index)