2010-08-08 3 views
16

Я хочу сделать sth. например:Удалить запись из массива

foo=(a b c) 
foo-=b 
echo $foo # should output "a c" 

Как удалить запись из массива? foo-=b не работает.

Удаление должно работать независимо от того, где находится запись.

ответ

26

Чтобы удалить элемент номер $i: a=("${(@)a[1,$i-1]}" "${(@)a[$i+1,$#a]}")

(Чем проще конструкция a=($a[1,$i-1] $a[$i+1,$#a]) также удаляет пустые элементы.)

Добавлено:

Для того, чтобы удалить любое вхождение b: a=("${(@)a:#b}")
:# является иероглиф для удаления соответствующих элементов; "" и (@) должны корректно работать с массивами, даже если они содержат пустые элементы.

+0

Это выглядит довольно сложно. Кроме того, как мне получить '$ i'? Я просто хочу удалить 'b'. – Albert

+0

@Albert: Я добавил, как удалить содержимое. – Gilles

+0

Спасибо, это дополнение именно то, что я хотел. – Albert

4

foo = (1 2 3)

shift foo

print $foo дает: 2 3

Так что это удаляет первый элемент (это то, что вы хотите?)

[отредактированный]

удалить i-й элемент с

foo[$i] =()

вместо этого.

+0

Это работает только в том случае, если запись указана в индексе 0. – Albert

+0

Нет, я хочу удалить запись где бы то ни было (она не всегда в начале). – Albert

+0

Что такое '$ i'? Как мне это получить? – Albert

2

Чтобы удалить элемент с содержанием «Ъ» из массива:

foo=(a b c) 
foo=(${foo#b}) 
+0

Это преобразует '(foo bar foobar)' в '(bar bar)'! – blueyed

+0

Нет, это не так: 'foo = (foo bar foobar); foo = ($ {foo # bar}); echo $ foo' возвращает 'foo foobar'. –

+1

Неверно:' foo = (a ab ac ad); foo = ($ {foo # a}); declare foo' дает 'foo = (b c d)' (ожидается 'foo = (ab ac ad)'). –

15

Жиль второго ответа является правильным, если вы хотите, чтобы удалить все вхождения, но это полное переназначение массива и не учитывает ситуацию где вы хотите удалить только одну запись, независимо от дубликатов.Существует способ, в Zsh, чтобы удалить элемент из нормального массива без переназначения всего массива:

Учитывая следующий массив:

array=(abc def ghi) 

следующее возвращает индекс первого матча за def:

${array[(i)def]} 

и следующий формат может быть использован для удаления любого заданного значения, индексированную (индекс элемента 2 в этом примере) в массиве без переназначения всего массива:

array[2]=() 

, таким образом, чтобы удалить значение def мы объединить два:

array[$array[(i)def]]=() 

Это очиститель для одного удаления элемента, так как нет переназначение явного массива (очиститель в том, что любые потенциальные побочные эффекты, такие, как случайное удаление пустых предметов, проблемы с указанным форматом и т. д. не собираются возникать). Однако решение Gilles в значительной степени эквивалентно и имеет преимущество при удалении нескольких совпадающих элементов, если это то, что вы хотите. С его методом и этим методом у вас есть полный набор инструментов для удаления элемента стандартного массива.

+0

Отличный ответ! Хорошо объяснил, upvote! – jpoppe

Смежные вопросы