Tuesday, April 22, 2008

Sorting multidimensional arrays in Groovy

I didn't find this solution as quickly as I thought I would so I thought I would post about it here to provide some search engine fodder.

If you are dealing with multidimensional arrays in Groovy (ref: http://groovy.codehaus.org/JN1025-Arrays ) and want to sort them you can expand on the sorting concepts for collections in Groovy (ref: http://groovy.codehaus.org/JN1015-Collections ).

If you look in the last reference you will find the example:
def mc= [
compare: {a,b-> a.equals(b)? 0: Math.abs(a)<Math.abs(b)? -1: 1 }
] as Comparator
We can modify this for a multidimensional array. So some excerpts from my code:
println "Pre sort: ${uniqueAges}"
def mc = [
compare: {a, b -> a[0].equals(b[0]) ? 0 : a[0] < b[0] ? -1 : 1 }
] as Comparator
println "Post sort: ${uniqueAges.sort(mc)}"
results in
Pre sort: [[11.2, 5.32], [1.77, 0.01], [3.58, 1.77], [5.32, 1.77], [5.32, 3.58]]
Post sort: [[1.77, 0.01], [3.58, 1.77], [5.32, 1.77], [5.32, 3.58], [11.2, 5.32]]
or
 println "Pre sort: ${ageZoneList}"
def mc2 = [
compare: {a, b -> a[0][0].equals(b[0][0]) ? 0 : a[0][0] < b[0][0] ? -1 : 1 }
] as Comparator
println "Post sort: ${ageZoneList.sort(mc2)}"
results in
Pre sort: [[[5.32, 11.2], [163.5, 189.62, "Late Miocene"]], [[0.01, 1.77], [0.05, 105.58, "Pleistocene"]], [[1.77, 3.58], [114.82, 123.68, "Late Pliocene"]], [[1.77, 5.32], [103.13, 163.53, "Pliocene"]], [[3.58, 5.32], [137.16, 156.19, "Early Pliocene"]]]
Post sort: [[[0.01, 1.77], [0.05, 105.58, "Pleistocene"]], [[1.77, 3.58], [114.82, 123.68, "Late Pliocene"]], [[1.77, 5.32], [103.13, 163.53, "Pliocene"]], [[3.58, 5.32], [137.16, 156.19, "Early Pliocene"]], [[5.32, 11.2], [163.5, 189.62, "Late Miocene"]]]


Note that in Groovy multidimensional arrays need not have the same exact length at each level as noted in the Array reference above. This does mean that you need to take care with respect to iterating your indexes if your array is triangular. This is not likely the most efficient search for a large multidimensional array, but for simple sorts on smaller examples its working well for me. I would appreciate references for quicker sorts if people have them.

take care
Doug

No comments: