Bash indirect reference to an associative array

丶灬走出姿态 提交于 2019-11-30 08:45:20

问题


In this very simplified example, I need to address both key and value of an array element:

declare -A writer
writer[H.P.]=Lovecraft
writer[Stephen]=King
writer[Clive]=Barker
writer[Jack]=Ketchum

for i in ${!writer[@]}
do
    echo "$i ${writer[$i]}"
done

fullname()
{
    pointer=$1[@]
    for i in "${!pointer}"
    do
        echo "? $i"
    done
}
fullname writer

The function must display the output in the same format as the example loop before it, and it should receive either array name, list of keys or values, all of which I tried, without success. Any suggestions are greatly appreciated.


回答1:


indir_keys() {
    eval "echo \${!$1[@]}"
}

indir_val() {
    eval "echo \${$1[$2]}"
}

fullname()
{
    pointer=$1
    for i in $(indir_keys $pointer)
    do  
        echo "$i $(indir_val $pointer $i)"
    done
}

Gives:

Jack Ketchum
Clive Barker
Stephen King
H.P. Lovecraft



回答2:


Since Bash 4.3, declare has a flag -n to define references (this is loosely equivalent to references in C++). This flag tremendously simplifies your problem here:

fullname() {
    declare -nl pointer="$1"
    for i in "${!pointer[@]}"
    do
        echo "${pointer[$i]} $i"
    done
}

It will be safe if you're having spaces or funny symbols in the keys of your hash (unlike the accepted answer).




回答3:


From the Bash Reference Guide:

The positional parameters are temporarily replaced when a shell function is executed (see Shell Functions).

So you could do this:

fullname()
{
    for first
    do
        echo "$first ${writer[$first]}"
    done
}
fullname "${!writer[@]}"


来源:https://stackoverflow.com/questions/27456950/bash-indirect-reference-to-an-associative-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!