Reputation: 11978
Does Groovy have a smart way to check if a list is sorted? Precondition is that Groovy actually knows how to sort the objects, e.g. a list of strings.
The way I do right now (with just some test values for this example) is to copy the list to a new list, then sort it and check that they are equal. Something like:
def possiblySorted = ["1", "2", "3"]
def sortedCopy = new ArrayList<>(possiblySorted)
sortedCopy.sort()
I use this in unit tests in several places so it would be nice with something like:
def possiblySorted = ["1", "2", "3"]
possiblySorted.isSorted()
Is there a good way like this to check if a list is sorted in Groovy, or which is the preffered way? I would almost expect Groovy to have something like this, since it is so smart with collections and iteration.
Upvotes: 12
Views: 5346
Reputation: 19219
If you want to avoid doing an O(n*log(n)) operation to check if a list is sorted, you can iterate it just once and check if every item is less or equals than the next one:
def isSorted(list) {
list.size() < 2 || (1..<list.size()).every { list[it - 1] <= list[it] }
}
assert isSorted([])
assert isSorted([1])
assert isSorted([1, 2, 2, 3])
assert !isSorted([1, 2, 3, 2])
Upvotes: 13
Reputation: 171144
Why not just compare it to a sorted instance of the same list?
def possiblySorted = [ 4, 2, 1 ]
// Should fail
assert possiblySorted == possiblySorted.sort( false )
We pass false
to the sort method, so it returns a new list rather than modifying the existing one
You could add a method like so:
List.metaClass.isSorted = { -> delegate == delegate.sort( false ) }
Then, you can do:
assert [ 1, 2, 3 ].isSorted()
assert ![ 1, 3, 2 ].isSorted()
Upvotes: 9