我想要做像这样的事情:
foo=(a b c)
foo-=b
echo $foo # should output "a c"
如何从数组中删除一个元素? foo-=b
无法实现此功能。
删除操作应该不受元素位置的限制。
要删除元素编号为$i
的元素: a=("${(@)a[1,$i-1]}" "${(@)a[$i+1,$#a]}")
(简化的语法a=($a[1,$i-1] $a[$i+1,-1])
也可以删除空元素。)
添加:
要删除任何匹配的b
元素: a=("${(@)a:#b}")
:#
是用于删除匹配的符号,""
和(@)
可使其在数组中正确操作即使它们包含空元素。
如果您希望删除所有出现的内容,则Gilles第二个答案是正确的,但它会完全重新分配数组,并且无法解决您仅希望删除单个条目的情况,而不管重复项如何。在zsh中,有一种方法可以从正常的数组中删除元素,而无需重新分配整个数组:
假设有以下数组:
array=(abc def ghi)
以下代码将返回第一个匹配项的索引位置def
:
${array[(i)def]}
下面的格式可以用来从数组中删除任何给定的索引值(在此示例中为元素索引2),而无需重新分配整个数组:
array[2]=()
因此,要删除值def
,我们将两个值组合:
array[$array[(i)def]]=()
对于单个元素的删除,这种方法更为简洁,因为没有显式的数组重新分配(更加简洁,避免了任何潜在的副作用,例如意外删除空项、引号格式问题等)。但是,Gilles的解决方案在很大程度上是等效的,并且具有多个匹配项删除的优势,如果这正是您想要的。使用他的方法和这种方法,您将拥有一个完整的工具集,用于标准数组元素的删除。
(I)
来删除最后一个匹配项而不是第一个。在i
/I
标志后添加e
以获得精确匹配;在这里,zsh
通常进行模式匹配,即def*
将删除以def
开头的第一个元素。 - Martin von Wittichfoo = (1 2 3)
shift foo
print $foo
会输出:2 3
这将删除第一个元素(您想要的是这个吗?)
[编辑]
要删除第i个元素,请使用以下代码:
foo[$i] = ()
即可。
$i
是什么?我该如何获取它? - Albert$i=b
吗?那是不行的。 foo(b)=()
是无效的。 - Alberti=2
,这是这个答案中最后一个选项的意图。然而,这不是你要找的。 - Dennis Williamsonfoo=(a b c)
foo=(${foo#b})
(foo bar foobar)
转换为 (bar bar)
! - blueyedfoo=(foo bar foobar) ; foo=(${foo#bar}) ; echo $foo
返回 foo foobar
。 - docwhatfoo=(a ab ac ad) ; foo=(${foo#a}) ; declare foo
输出 foo=(b c d)
(期望输出 foo=(ab ac ad)
)。 - Franklin Yufoo#foo
而不是 foo#bar
。 - Dessa Simpsonfoo=(foo bar foobar barfoo); foo=(${foo#bar}); declare foo
返回 foo=( foo foobar foo )
。 - Dessa Simpson
a=("${(@)a[1,
...应该是a=("${(@)a[0,
(从0开始)。 - phil294${a:#}
被解析为${VARIABLE:#PATTERN}
参数扩展结构,而不是${VARIABLE:INDEX}
结构。此外,${a:$#a}
不会删除最后一个元素,它将从最后一个元素之后开始取一个切片,因此它将是一个空数组。 - Gilles 'SO- stop being evil'