Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy way to check if a list is sorted or not

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.

like image 328
Magnilex Avatar asked Feb 28 '13 09:02

Magnilex


People also ask

How do I check if an ArrayList is sorted?

Instead just iterate over the list and check that the current element is greater or equal than the previous. If your list should be sorted in descending order check that the current element is less or equal than previous. Obviously the comparison of elements may be done using custom Comparator . Save this answer.

How do I check if a string is sorted?

Iterative Approach The iterative approach is a simple and intuitive way to check for a sorted list. In this approach, we'll iterate the list and compare the adjacent elements. If any of the two adjacent elements are not sorted, we can say that the list is not sorted.

How can you tell if an array is in ascending order?

Recursive approach: 1: If size of array is zero or one, return true. 2: Check last two elements of array, if they are sorted, perform a recursive call with n-1 else, return false. If all the elements will be found sorted, n will eventually fall to one, satisfying Step 1.


2 Answers

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])
like image 148
epidemian Avatar answered Sep 19 '22 07:09

epidemian


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()
like image 42
tim_yates Avatar answered Sep 21 '22 07:09

tim_yates