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.


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.


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

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

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
~
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.