我想创建一个迭代数组并插入给定值的函数(如果尚未包含它)。我在我的代码的两个不同部分使用此函数,因此我必须使用不同的数组。因此我将数组名称传递给函数。现在我无法弄清楚如何分配数组的一个插槽来存储元素。
这是我的代码:
name=("hello" "world")
function f {
array_name=$2[@]
array=("${!array_name}")
length=${#array_name[@]}
for (( i = 0; i <= $length; i++ )); do
if [[ "${array[i]}" = "$1" ]];
break;
fi
if [[ "$i" = "$length" ]]; then
${2[$length+1]=$1};
fi
done
}
f "test" "name"
编辑:我希望数组附加给定值,如下所示
for i in ${name[@]}
do
echo $i
done
会有这个输出:
hello
world
test
但显然"${2[$length+1]=$1}"
无效。
(传递数组的想法来自这里:bash how to pass array as an argument to a function)
答案 0 :(得分:6)
如果我理解正确,如果该值尚未在数组中,则要向数组附加值,但棘手的部分是将数组名称传递给函数。
一种可能性是从不同的角度看问题:您可以将要插入的值和完整数组传递给函数,该函数将设置一个全局变量,您将在执行后恢复该变量。对于我们的测试示例,我们将使用:
array=( hello world "how are you today?" )
我们会尝试插入test
和hello
(这样就不会插入hello
):
f() {
# This function will set the global variable _f_out to an array obtained from
# the positional parameters starting from position 2, with $1 appended if and
# only if $1 doesn't appear in the subsequent positional parameters
local v=$1 i
shift
_f_out=( "$@" )
for i; do [[ $i = $v ]] && return; done
_f_out+=( "$v" )
}
让我们用它:
$ array=( hello world "how are you today?" )
$ f test "${array[@]}"
$ array=( "${_f_out[@]}" )
$ printf '%s\n' "${array[@]}"
hello
world
how are you today?
test
$ f hello "${array[@]}"
$ array=( "${_f_out[@]}" )
$ printf '%s\n' "${array[@]}"
hello
world
how are you today?
test
有效。
备注。我使用了for i; do
。这是for i in "$@"; do
的一个很好的捷径。
你真的想摆弄simili-pointers并做好追加(这不是真正的Bash精神 - 这就是为什么它有点笨拙)。其工具是将printf
与-v
选项一起使用:来自help printf
:
-v var assign the output to shell variable VAR rather than display it on the standard output
好处是它也适用于数组字段。
警告:您可能会看到其他使用eval
的方法。像瘟疫一样避免它们!
f() {
local array_name=$2[@] i
local array=( "${!array_name}" )
for i in "${array[@]}"; do [[ $i = $1 ]] && return; done
# $1 was not found in array, so let's append it
printf -v "$2[${#array[@]}]" '%s' "$1"
}
让我们试一试:
$ array=( hello world "how are you today?" )
$ f test array
$ printf '%s\n' "${array[@]}"
hello
world
how are you today?
test
$ f hello array
$ printf '%s\n' "${array[@]}"
hello
world
how are you today?
test
它也有效。
注意。使用这两种方法,您可以非常轻松地获得函数的return
代码,例如0
(成功),如果插入了值,则{{} 1}}(失败)如果价值已经存在(或反过来) - 适应是直截了当的,并留作练习。这在方法1中可能很有用,可以确定是否需要将1
更新为返回值array
。在这种情况下,您甚至可以稍微修改_f_out
,以便当值已经在数组中时它甚至不会设置f
。
警告。在所示的两种方法中,我假设您的数组具有从0开始的连续索引(即非稀疏数组)。我认为这是一个安全的假设;但如果不是这样,那么这些方法就会被破坏:第一个方法将(在重新分配后)将数组转换为非稀疏方法,第二个方法可能会覆盖字段(对于数组_f_out
, a
扩展为数组中的元素数,而不是数组中找到的最高索引+ 1。