Groovy list shift and unshift

JRE methods List.remove(int) and List.add(int, E) are supersets of shift and unshift operations, making this trivial for groovy. No reason to involve other classes as other people are proposing.

def baseList = ['one', 'two', 'three']

// Unshift operation:
baseList.add(0, 'zero')
assert  ['zero', 'one', 'two', 'three'] == baseList

// Shift operation
assert  'zero' == baseList.remove(0)
assert  ['one', 'two', 'three'] == baseList

(dummy text to satisfy stackoverflow edit)


If you need to add and remove from the front, you may want to use an implementation of a Java Deque for your lists. This data structure specifically allows efficient additions and removals from either end.

It has methods push() and pop() for adding and removing elements from the beginning. addFirst() and removeFirst() are alternative names that do the same thing.

Example:

def list = new ArrayDeque([1, 2, 3, 4, 5])
def firstElement = list.pop()
assert firstElement == 1
list.push(0)
assert list as List == [0, 2, 3, 4, 5]

There's no built in shift and unshift... Here are some options:

You could use a queue:

def queue = [ 1, 2, 3, 4, 5 ] as Queue

def firstElement = queue.poll()

assert firstElement == 1
assert queue == [ 2, 3, 4, 5 ]

But adding back in with offer adds to the wrong end, so use offerFirst:

queue.offerFirst( 1 )
assert queue == [ 1, 2, 3, 4, 5 ]

Or you could use a Stack, but you'd need to reverse your list to get 1 as the first element off of it.

def stack = [ 1, 2, 3, 4, 5 ].reverse() as Stack

def firstElement = stack.pop()

assert firstElement == 1
assert stack == [ 5, 4, 3, 2 ]

stack.push( 1 )
assert stack == [ 5, 4, 3, 2, 1 ]

Or, you could go the long way round:

def list = [ 1, 2, 3, 4, 5 ]

(firstElement, list) = [ list.head(), list.tail() ]

assert firstElement == 1
assert list == [ 2, 3, 4, 5 ]

list.add( 0, 1 )
assert list == [ 1, 2, 3, 4, 5 ]

Or you could add shift and unshift to the metaClass of List:

List.metaClass.shift = {
    delegate.remove( 0 )
}
List.metaClass.unshift = { val ->
    delegate.add( 0, val )
    delegate
}

def list = [ 1, 2, 3, 4, 5 ]
def firstElement = list.shift()
assert firstElement == 1
assert list == [ 2, 3, 4, 5 ]

list.unshift( 1 )
assert list == [ 1, 2, 3, 4, 5 ]

Tags:

List

Groovy