Arrays 如何分配按名称传递给函数的数组
我想创建一个函数,它遍历一个数组并插入给定的值(如果尚未包含该值的话)。我在代码的两个不同部分使用这个函数,所以我必须使用不同的数组。因此,我将数组名传递给函数。现在我不知道如何分配数组的一个插槽来存储这个位置上的元素 这是我的密码:Arrays 如何分配按名称传递给函数的数组,arrays,bash,Arrays,Bash,我想创建一个函数,它遍历一个数组并插入给定的值(如果尚未包含该值的话)。我在代码的两个不同部分使用这个函数,所以我必须使用不同的数组。因此,我将数组名传递给函数。现在我不知道如何分配数组的一个插槽来存储这个位置上的元素 这是我的密码: name=("hello" "world") function f { array_name=$2[@] array=("${!array_name}") length=${#array_name[@]} for (( i = 0
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"
将有以下输出:
hello
world
test
但显然“${2[$length+1]=$1}”不起作用
(传递数组的想法是从这里开始的:)如果我理解正确,您希望在数组中附加一个值,如果该值还不在数组中,但棘手的是数组名被传递给函数 方法1 一种可能是从另一个角度来看问题:您可以将要插入的值和完整数组传递给函数,函数将设置一个全局变量,您将在执行后恢复该变量。对于我们的测试示例,我们将使用:
array=( hello world "how are you today?" )
我们将尝试插入test
和hello
(这样就不会插入hello
):
让我们使用它:
$ 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
它起作用了
评论。我用表示我;执行
。对于“$@”中的i来说,这是一个很好的快捷方式;执行
方法2
你真的想摆弄simili指针,并在适当的位置进行附加(这并不符合Bash的精神,这就是为什么它有点笨拙的原因)。该工具是使用带有-v
选项的printf
:fromhelp printf
:
好的方面是,它也适用于数组字段
警告:您可能会看到其他使用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
它也有效
注意。使用这两种方法,您可以很容易地获得函数的返回
代码,例如,如果插入了值,则返回0
(成功);如果值已经存在(或相反),则返回1
(失败)-自适应非常简单,只需练习即可。在方法1中,这可能有助于确定是否需要将array
更新为返回值\u f\u out
。在这种情况下,您甚至可以稍微修改f
,这样当值已经在数组中时,它甚至不会设置\u f\u out
注意。在显示的两种方法中,我假设数组的连续索引从0开始(即非稀疏数组)。我认为这是一个安全的假设;但如果不是这样,这些方法就被破坏了:第一个方法(在重新分配后)将数组转换为非稀疏数组,第二个方法可能会覆盖字段(例如,对于数组
a
,${a[@]}
扩展到数组中的元素数,而不是数组中的最高索引+1).我想将参数1的值存储在参数2中数组的位置长度+1处。有趣的问题,但缺少键定义,需要从示例输入输出。(请补充上述问题,而不是作为评论)。祝你好运。首先:谢谢你!我认为我的观点更倾向于面向对象。我是bash新手,所以在理解您的代码时遇到了一些困难。我想要实现的是,实际使用全局数组(我正在传递给函数的名称),并将传递的值“test”附加到它。我想通过替换字符串来实现这一点。据我所知,第一个方法将创建一个新的全局数组,而不是扩展我已经创建的数组。在方法2中,我不理解值是如何附加到数组的。我还发现你可以用+=而不是数组[I]=。@telina在方法2中,它是这样一行:printf-v“$2[${{{{{}数组[@]}”'%s'$1}
附加值:如果你的数组名是ary
,并且有42个元素,“$2[${{{{}数组[@}]”
扩展到ary[42]
@telina您可以+=
附加到数组中,但这不适用于间接寻址,因此这里没有选项。
-v var assign the output to shell variable VAR rather than
display it on the standard output
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