在zsh中,如何将匿名数组传递到函数中?

8
在zsh中,如何将匿名数组传递给函数?例如,寻找类似以下的内容:
foo() {
  echo ${1[2]} '\n';
}

a=(abc def ghi)
foo $a

--> def

最理想的情况是:
foo (abc def ghi)

请注意,上面的内容实际上都不起作用。 - Aaron Fi
最好重新命名和改述这个问题,因为你自己的答案不是针对所陈述的问题。为了保留其他答案的价值,最好重新发布实际的问题,然后接受一个正确的答案。 - ocodo
5个回答

11
您可以将数组的名称传递给函数,然后函数可以通过将名称解释为变量名来读取数组。这是一种技术,在bash中也对类似关联数组的东西非常有用。在ZSH中,使用(P)运算符可以方便地按所需方式解释变量。
一个例子将说明这一点。如果您定义以下函数:
function i_want_array () {
    local array_name=$1

    echo "first array element is: " ${(P)${array_name}[1]}
}

那么以下代码将执行它:

% a=(one two three)
% i_want_array "a"
first array element is:  one

仅为澄清起见,这是通过对实际数组进行操作来实现的,因此任何空格都会被正确处理:

% a=("one two" three)
% i_want_array "a"
first array element is:  one two

这个魔法可行 :) 不过有一个重要的概念:本地变量的名称不能与存储数组值的外部变量相同。即在上面的示例中,外部变量是 a,而本地变量是 array_name。如果您有这两个同名变量,则解决方案将无法正常工作。 - vladZams

5

你不能这样做。函数像其他命令一样需要位置参数。

还要注意,你的解决方法不允许任何“数组”元素包含空格。

我能想到最干净的方法是要求调用者创建一个本地数组,然后从函数中读取它:

$ foo() {
   for element in $FOO_ARRAY
   do
       echo "[$element]"
   done
}
$ local FOO_ARRAY; FOO_ARRAY=(foo bar baz quux)
$ foo
[foo]
[bar]
[baz]
[quux]

我知道bash也有类似的自动补全系统,而且我认为zsh也有。这并不是太不寻常的。


谢谢。这解决了我的问题,即如何在函数中创建一个数组并以最简单的方式在使用后取消它。答案:local - Denis Howe

1
如果您只需要一个数组参数:作为尾部参数。
foo() {
  : if you have any leading non-array args, grab those first:
  local arg1="$1"
  shift
  local arg2="$1"
  shift
  : now $@ is your array arg
  echo $@[2] '\n';
}

a=(abc def ghi)
foo "arg 1" arg2 $a

--> def

有趣的是,就我所知,这在bash和zsh中都可以正常工作。 - JL Peyret

0

无法使用匿名数组解决...但我在BASH中尝试了这个东西!!...

function join {
  local tmp=($1)

  for (( i=0 ; i<${#tmp[@]}-1 ; i++ )) ; do
    echo -n ${tmp[$i]}$2
  done

  echo ${tmp[$i]}
}

test="abc def ghi"

join "$test" "|"

-3

找到了一个解决方法:

foo() {
  local a=$1
  local b=$2

  echo ${(j:---:)${=b}}

  foreach d in ${${=b}}
  do
      echo $d
  done
}

其中parameter2是一个由空格分隔的字符串,例如:'a badkljf odod'


3
这可能是你特定未表达需求的解决方法,但与问题几乎无关。这是对问题“如何分割参数?”的回答。 - peth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接