Groovy list.sort by first, second then third elements

前端 未结 7 1155
旧时难觅i
旧时难觅i 2021-02-02 09:42

I have a groovy list of lists i.e.

list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]

I would like sort it by order of the first element, then second, th

相关标签:
7条回答
  • 2021-02-02 09:56

    Done the Groovy way, regardless of the size of sub-lists:

    ll2.sort { l1, l2 ->
      e1e2 = [l1, l2].transpose().find { e1, e2 ->
          e1 != e2
      }
      e1e2 ? e1e2[0] <=> e1e2[1] : 0
    }
    
    0 讨论(0)
  • 2021-02-02 10:00

    If you want to sort arrays of arbitrary (though homogenous) length, you can use this and it will do it in a single pass:

    def list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]
    
    list.sort { a, b -> 
        for (int i : (0..<a.size())) {
            def comparison = (a[i] <=> b[i])
            if (comparison) return comparison
        } 
        return 0
    }
    
    assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]
    
    0 讨论(0)
  • 2021-02-02 10:00

    Here is another method using Groovy's Spaceship and Elvis operators:

    ​def list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]
    
    list.sort { a, b ->
       a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]
    }
    
    assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]​
    

    Source: Groovier way of sorting over multiple fields in a list of maps in groovy

    0 讨论(0)
  • 2021-02-02 10:01

    You should be able to iterate through the desired sorting in reverse order:

    list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]
    
    list = list.sort{ a,b -> a[2] <=> b[2] }
    list = list.sort{ a,b -> a[1] <=> b[1] }
    list = list.sort{ a,b -> a[0] <=> b[0] }
    
    assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]
    

    Each should override the previous just enough to keep the combined sorting intact.


    You can also chain them in order with the Elvis operator, ?:, which will defer to the next comparison when the previous are equal (and <=> returns 0):

    list.sort { a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2] }
    
    0 讨论(0)
  • 2021-02-02 10:04

    you can use kobo-commons' CollectionUtils library.

    https://github.com/kobo/kobo-commons/wiki/sort-by-multiple-keys

    import org.jggug.kobo.commons.lang.CollectionUtils
    
    CollectionUtils.extendMetaClass()
    
    
    list = [[2, 0, 1], [1, 5, 2], [1, 0, 3]]
    list = list.sort{ [ it[0], it[1], it[2] ]} // sort by multiple keys
    assert list == [[1, 0, 3], [1, 5, 2], [2, 0, 1]]
    
    list2 = [ [name:"a", age:13], [name:"a",age:15], [name:"b", age:13] ]
    list2 = list2.sort{[it.name, it.age] } // sort by name and age
    assert list2 == [[name:"a", age:13], [name:"a", age:15], [name:"b", age:13]]
    
    0 讨论(0)
  • 2021-02-02 10:07

    Here's what I came up with, not the most groovy way I suppose..

    list = list.sort{ a,b -> 
        if(a[0].compareTo(b[0]) == 0) {
            if(a[1].compareTo(b[1]) == 0) {
                return a[2].compareTo(b[2]);
            } else {
                return a[1].compareTo(b[1]);
            }
        } else {
            return a[0].compareTo(b[0]);
        }
    }
    
    0 讨论(0)
提交回复
热议问题