Is there really no built-in way to 'shift' and 'unshift' with lists in groovy? (something that ruby, javascript have) For instance:
def list = [1,2,3,4,5]
firstElement = list.shift
println firstElement // 1
println list // [2,3,4,5]
list.unshift 1
println list // [1,2,3,4,5]
If no built in way, are there conventional alternatives?
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 ]
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With