Groovy сдвиг списка и смещение
Нет ли встроенного способа "сдвинуть" и "не переключать" со списками в groovy? (что-то, что Ruby, javascript) Например:
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]
Если нет встроенных способов, существуют ли обычные альтернативы?
Ответы
Ответ 1
Нет встроенных сдвигов и смещения... Вот несколько вариантов:
Вы можете использовать очередь:
def queue = [ 1, 2, 3, 4, 5 ] as Queue
def firstElement = queue.poll()
assert firstElement == 1
assert queue == [ 2, 3, 4, 5 ]
Но добавление обратно с помощью offer
добавляет неверный конец, поэтому используйте offerFirst
:
queue.offerFirst( 1 )
assert queue == [ 1, 2, 3, 4, 5 ]
Или вы можете использовать Stack
, но вам нужно будет отменить свой список, чтобы получить 1
в качестве первого элемента.
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 ]
Или вы могли бы пройти долгий путь:
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 ]
Или вы можете добавить shift
и unshift
в metaClass из списка:
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 ]
Ответ 2
Если вам нужно добавить и удалить с фронта, вы можете использовать реализацию Java Deque для своих списков. Эта структура данных специально позволяет эффективно добавлять и удалять с любого конца.
Он имеет методы push()
и pop()
для добавления и удаления элементов с самого начала. addFirst()
и removeFirst()
являются альтернативными именами, которые делают то же самое.
Пример:
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]
Ответ 3
Методы JRE List.remove(int)
и List.add(int, E)
являются надмножествами операций сдвига и отмены, что делает это тривиальным для groovy. Нет причин привлекать другие классы, как предлагают другие люди.
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
(фиктивный текст, чтобы удовлетворить редактирование stackoverflow)