Cara mengulangi array asosiatif di Bash

351

Berdasarkan pada array asosiatif dalam skrip Bash, saya perlu mengulanginya untuk mendapatkan kunci dan nilai.

#!/bin/bash

declare -A array
array[foo]=bar
array[bar]=foo

Saya sebenarnya tidak mengerti cara mendapatkan kunci saat menggunakan for-in loop.

pex
sumber
14
$ declare -A array = ([foo] = bar [bar] = foo) # Inisialisasi sekaligus
anisbet
3
Untuk daftar kecil nilai-nilai utama Anda dapat mempertimbangkan ini:for i in a,b c_s,d ; do KEY=${i%,*}; VAL=${i#*,}; echo $KEY" XX "$VAL; done
matematika

Jawaban:

582

Tombol yang diakses menggunakan tanda seru: ${!array[@]}, yang nilai diakses menggunakan ${array[@]}.

Anda dapat mengulangi pasangan kunci / nilai seperti ini:

for i in "${!array[@]}"
do
  echo "key  : $i"
  echo "value: ${array[$i]}"
done

Perhatikan penggunaan tanda kutip di sekitar variabel dalam forpernyataan (ditambah penggunaan @bukan *). Ini diperlukan jika ada kunci yang memasukkan spasi.

Kebingungan dalam jawaban lain berasal dari fakta bahwa pertanyaan Anda termasuk "foo" dan "bar" untuk kunci dan nilainya.

Dijeda sampai pemberitahuan lebih lanjut.
sumber
3
Ini sekarang jika menetapkan semua kunci ke array:array=(${!hash[@]})
Michael-O
12
@ Michael-O: Anda perlu mengutip ekspansi parameter untuk melindungi kunci yang mungkin memiliki spasi putih:array=("${!hash[@]}")
Dijeda hingga pemberitahuan lebih lanjut.
@ DennisWilliamson, terima kasih banyak. Saya tidak memiliki ini di pikiran saya.
Michael-O
Bagaimana kita bisa menggunakan nomor argumen fungsi alih-alih variabel? misalnya for i in "${!$1[@]}"?
pkaramol
2
@ pkaramol: Mulai di Bash 4.3 Anda bisa menggunakan namerefs. Contoh: declare -A aa; aa['A']=a1; aa['B']=b2; aa['C']=c3; foo () { declare -n assoc=$1; for key in "${!assoc[@]}"; do echo "Key: $key; Value: ${assoc[$key]}"; done; }; foo aa. Silakan lihat BashFAQ / 006 untuk beberapa informasi penting.
Dijeda sampai pemberitahuan lebih lanjut.
42

Anda dapat mengakses kunci dengan ${!array[@]}:

bash-4.0$ echo "${!array[@]}"
foo bar

Kemudian, beralih ke pasangan kunci / nilai mudah:

for i in "${!array[@]}"
do
  echo "key :" $i
  echo "value:" ${array[$i]}
done
tonio
sumber
1
Saya punya "!" - bahkan tidak memperhatikan, tidak ada, maaf .. :)
pex
8

Gunakan fungsi tingkat tinggi ini untuk mencegah piramida malapetaka

foreach(){ 
  arr="$(declare -p $1)" ; eval "declare -A f="${arr#*=}; 
  for i in ${!f[@]}; do $2 "$i" "${f[$i]}"; done
}

contoh:

$ bar(){ echo "$1 -> $2"; }
$ declare -A foo["flap"]="three four" foo["flop"]="one two"
$ foreach foo bar
flap -> three four
flop -> one two
koderofsalvasi
sumber
1
Saya tidak yakin bagaimana ini berlaku? Bukankah piramida malapetaka adalah masalah estetika murni dan benar-benar hanya berlaku dalam bahasa berorientasi objek?
Alexej Magura
1
Bisakah Anda menjelaskannya? Fungsi foreach agak rumit. Saya tidak mengerti.
Bálint Szigeti
-1
declare -a arr
echo "-------------------------------------"
echo "Here another example with arr numeric"
echo "-------------------------------------"
arr=( 10 200 3000 40000 500000 60 700 8000 90000 100000 )

echo -e "\n Elements in arr are:\n ${arr[0]} \n ${arr[1]} \n ${arr[2]} \n ${arr[3]} \n ${arr[4]} \n ${arr[5]} \n ${arr[6]} \n ${arr[7]} \n ${arr[8]} \n ${arr[9]}"

echo -e " \n Total elements in arr are : ${arr[*]} \n"

echo -e " \n Total lenght of arr is : ${#arr[@]} \n"

for (( i=0; i<10; i++ ))
do      echo "The value in position $i for arr is [ ${arr[i]} ]"
done

for (( j=0; j<10; j++ ))
do      echo "The length in element $j is ${#arr[j]}"
done

for z in "${!arr[@]}"
do      echo "The key ID is $z"
done
~
EJISRHA
sumber