我想创建一个遍历数组并插入给定值(如果尚未包含)的函数。我在代码的两个不同部分使用了此函数,因此必须使用不同的数组。因此,我正在将数组名称传递给该函数。现在,我无法弄清楚如何分配数组的插槽以将元素存储在此位置。
这是我的代码:
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如何将数组作为参数传递给函数)
如果我理解正确,那么您想在数组中还没有附加值的情况下将其附加到数组中,但棘手的部分是将数组名传递给函数。
一种可能性是从不同的角度看问题:您可以将要插入的值和完整数组传递给函数,该函数将设置一个全局变量,在执行该变量后将对其进行恢复。对于我们的测试示例,我们将使用:
array=( hello world "how are you today?" )
并且我们将尝试插入test
and 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
。
您确实想摆弄类似指针并进行适当的附加操作(这并不是Bash真正的精神,这就是为什么它有点笨拙的原因)。该工具可printf
与以下-v
选项一起使用:from 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中确定是否需要更新array
为返回值时可能很有用_f_out
。在这种情况下,您甚至可以稍作修改,f
以便_f_out
在数组中已存在该值时甚至不进行设置。
警告。在所示的两种方法中,我都假定您的数组具有从0开始的连续索引(即,非稀疏数组)。我认为这是一个安全的假设;但是,如果不是这种情况,这些方法将被破坏:第一个方法(在重新分配后)会将数组转换为非稀疏方法,而第二个方法可能会覆盖字段(例如,对于array a
,${#a[@]}
扩展为数组中的元素,而不是数组中找到的最高索引+ 1)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句