从数组中删除条目

Alb*_*ert 23 arrays shell zsh

我想做某事.像这样:

foo=(a b c)
foo-=b
echo $foo # should output "a c"
Run Code Online (Sandbox Code Playgroud)

如何从数组中删除条目?foo-=b不起作用.

无论条目在何处,删除都应该有效.

Gil*_*il' 33

要删除元素编号$i:a=("${(@)a[1,$i-1]}" "${(@)a[$i+1,$#a]}")

(更简单的构造a=($a[1,$i-1] $a[$i+1,$#a])也会删除空元素.)

添加:

删除任何出现的b:a=("${(@)a:#b}")
:#是用于删除匹配元素的象形文字; ""并且(@)即使它们包含空元素,也要在数组上正确运行.


小智 25

Gilles第二个答案是正确的,如果你想删除所有出现,但它是一个完整的阵列重新分配,并没有解决你希望只删除一个条目的情况,无论重复.在zsh中有一种方法可以从正常数组中删除元素而无需重新分配整个数组:

给出以下数组:

array=(abc def ghi)
Run Code Online (Sandbox Code Playgroud)

以下将返回第一个匹配的索引def:

${array[(i)def]}
Run Code Online (Sandbox Code Playgroud)

并且以下格式可用于删除数组中的任何给定索引值(此示例中的元素索引2),而无需重新分配整个数组:

array[2]=()
Run Code Online (Sandbox Code Playgroud)

因此,要删除def我们将两者结合起来的值:

array[$array[(i)def]]=()
Run Code Online (Sandbox Code Playgroud)

这对于单个元素移除来说更清晰,因为没有明确的阵列重新分配(更清晰,因为任何潜在的副作用,例如意外删除空项目,引用格式问题等都不会突然出现).然而,Gilles的解决方案在很大程度上是等效的,并且具有多个匹配项目移除的优势,如果这是您想要的.使用他的方法和此方法,您可以获得用于标准数组元素删除的完整工具集.


Jér*_*ler 9

4.2 和 5.0版本开始, zsh 接受${name:|arrayname}语法。从手册

如果arrayname是数组变量的名称(注意,不是内容),arrayname则从 的替换中移除包含在其中的任何元素name

因此,它完全符合您的期望:

$ foo=(a b c)
$ excl=(b)
$ echo ${foo:|excl}
a c
Run Code Online (Sandbox Code Playgroud)


Hen*_*sma 7

foo = (1 2 3)

shift foo

print $foo 给:2 3

所以这删除了第一个元素(这是你想要的吗?)

[编辑]

删除第 i 个元素

foo[$i] =()

反而。