ScriptSpot

Forum topic · General Scripting

[example] How to sort multidimensional array

By barigazy · 2012-05-30

Description

I want to share with you guys my little try how to sort multidim array.
Hope someone this can help. If you have another good example for different type of sorting please post it here.

*SORTING MULTIDIM ARRAY BY NAME OR BY COUNT*


fn sortByNameOrCount arr1 arr2 type: maxtomin: =
(
	local first, second
	case type of (
		(#name): (first = arr1[1] ; second = arr2[1])
		(#count): (first = arr1[2].count ; second = arr2[2].count)
	)
	case of (
		(first < second): if not maxtomin then -1 else 1
		(first > second): if not maxtomin then 1 else -1
		default:0
	)
)

--example_#1 (sort by name alphabetically from Z to A)
multiArr = #(#("Branko",#(1,2,3,4)), #("John",#(1)), #("Richard",#(1,2,3)), #("Stalone",#(1,2,3,4,5)), #("Michael",#(1,2)))
qsort multiArr sortByNameOrCount type:#name maxtomin:true
multiArr
--result: #(#("Stalone", #(1, 2, 3, 4, 5)), #("Richard", #(1, 2, 3)), #("Michael", #(1, 2)), #("John", #(1)), #("Branko", #(1, 2, 3, 4)))

--example_#2 (sort by name alphabetically from A to Z)
multiArr = #(#("Branko",#(1,2,3,4)), #("John",#(1)), #("Richard",#(1,2,3)), #("Stalone",#(1,2,3,4,5)), #("Michael",#(1,2)))
qsort multiArr sortByNameOrCount type:#name maxtomin:false
multiArr
--result: #(#("Branko", #(1, 2, 3, 4)), #("John", #(1)), #("Michael", #(1, 2)), #("Richard", #(1, 2, 3)), #("Stalone", #(1, 2, 3, 4, 5)))

--example_#3 (sort by array count from max to min)
multiArr = #(#("Branko",#(1,2,3,4)), #("John",#(1)), #("Richard",#(1,2,3)), #("Stalone",#(1,2,3,4,5)), #("Michael",#(1,2)))
qsort multiArr sortByNameOrCount type:#count maxtomin:true
multiArr
--result:#(#("Stalone", #(1, 2, 3, 4, 5)), #("Branko", #(1, 2, 3, 4)), #("Richard", #(1, 2, 3)), #("Michael", #(1, 2)), #("John", #(1)))

--example_#4 (sort by array count from min to max)
multiArr = #(#("Branko",#(1,2,3,4)), #("John",#(1)), #("Richard",#(1,2,3)), #("Stalone",#(1,2,3,4,5)), #("Michael",#(1,2)))
qsort multiArr sortByNameOrCount type:#count maxtomin:false
multiArr
--result:#(#("John", #(1)), #("Michael", #(1, 2)), #("Richard", #(1, 2, 3)), #("Branko", #(1, 2, 3, 4)), #("Stalone", #(1, 2, 3, 4, 5)))

Comments (3)

maxLINQ sort

P3D_PathScripts · 2017-02-24

You can do it through maxLINQ:


-- Your same examples
(_From multiArr).Sort(#'x=>x[1]')	  --> example_#2 (sort by name alphabetically from A to Z)	
(_From multiArr).Sort(#'d:x=>x[1]')	  --> example_#1 (sort by name alphabetically from Z to A)
(_From multiArr).Sort(#'x=>x[2].count')	  --> example_#4 (sort by array count from min to max)
(_From multiArr).Sort(#'d:x=>x[2].count') --> example_#3 (sort by array count from max to min)

-- But you can go quite further. For example:
multiArr = #(#("branko",#(5,9,3,4,7,2,8)), #("John",#(6,5,7,8)), #("richard",#(4,8,5,6,9)), #("Stalone",#(1,2,3,4,5)), #("Michael",#(5,3,4,9,7,6)))
(_From multiArr).Sort(#'x=>(_From x[2]).Sum#()')	--> sort ascending by the sum of the numbers in the second item
(_From multiArr).Sort(#'d:x=>(_From x[2]).Sum#()')	--> sort descending by the sum of the numbers in the second item
(_From multiArr).Sort(#'x=>(_From x[2]).Average#()')	--> sort ascending by the average of  the numbers in the second item
(_From multiArr).Sort(#'d:x=>(_From x[2])._Min#()')	--> sort descending by the minimum value of  the numbers in the second item
(_From multiArr).Sort(#'x=>x[1]')			--> sort ascending by name (first item) case sensitive
(_From multiArr).Sort(#'ci:x=>x[1]')			--> sort ascending by name (first item) case insensitive
(_From multiArr).Sort(#'ci,d:x=>x[1]')			--> sort descending by name (first item) case insensitive
-- or even get the indices of the result ordered array in all the above cases with the "i:" modifier:
(_From multiArr).Sort(#'i:x=>(_From x[2]).Sum#()')	--> #(4, 2, 3, 5, 1)
(_From multiArr).Sort(#'ci,d,i:x=>x[1]')		--> #(4, 3, 5, 2, 1)

kimarotta · 2012-05-30

Very good, thanks for share ... very interesting.

barigazy · 2012-05-30

This function can be improved for sorting of different things