はじめに
タイトルの通りですが、連想配列をキーで sort した後、ループ処理させる実装方法を備忘録として残しています。
前提
連想配列が以下のように定義されているとします。
連想配列
declare -A daily_costs
daily_costs["20240101"]="200000"
daily_costs["20240102"]="400000"
daily_costs["20240103"]="150000"
daily_costs["20240104"]="260000"
daily_costs["20240105"]="330000"
daily_costs["20240106"]="210000"
daily_costs["20240107"]="500000"
daily_costs["20240108"]="1000000"
連想配列のキーはループさせる際に順不同なので、一工夫が必要です。
(今回のメインテーマになります)
取り出し順は保証されない
[ec2-user@localhost ~]$ echo ${!daily_costs[@]}
20240108 20240101 20240102 20240103 20240104 20240105 20240106 20240107
結論
以下のように記述すると、意図する sort 順で処理を実行することができます。
sort を考慮したループ処理
echo "${!daily_costs[@]}" | sed 's/ /\n/g' | sort -n | while read key
do
echo "日付: ${key}, コスト: ${daily_costs[${key}]}"
done
実行結果
日付: 20240101, コスト: 200000
日付: 20240102, コスト: 400000
日付: 20240103, コスト: 150000
日付: 20240104, コスト: 260000
日付: 20240105, コスト: 330000
日付: 20240106, コスト: 210000
日付: 20240107, コスト: 500000
日付: 20240108, コスト: 1000000
コマンドの説明
コマンド | やっていること |
---|---|
echo "${!daily_costs[@]}" | daily_costsのキーを全て取得(区切り文字は空白) |
sed 's/ /\n/g' | 取得したキーの区切り文字を、空白から改行に変更( sort が適切に働くようにするため) |
sort -n | 数値として、昇順でソート |
|
(パイプ)でコマンドをつなげることで、前の実行結果を後ろに渡すことができます。
そのため、上記のように while
文の前にコマンドを並べることで、ソートされたキーを順番に取り出してループ処理させることが可能になります。
応用
二つの連想配列を組み合わせて処理させたい場合があります。
例えば上記の例に加えて、売上用の連想配列を用意します。
売上用の連想配列
declare -A daily_earnings
daily_earnings["20240101"]="600000"
daily_earnings["20240103"]="1200000"
daily_earnings["20240105"]="1800000"
daily_earnings["20240107"]="2600000"
daily_earnings["20240109"]="3300000"
daily_earnings["20240110"]="900000"
daily_earnings["20240112"]="900000"
daily_earnings["20240114"]="1500000"
二つの連想配列のキーの和集合を使ってループ処理をするには、以下のように記述します。
uniq
: ソートされた文字列に対して、重複する行を一つにまとめるコマンド
キーの和集合を sort してループ処理
echo "${!daily_costs[@]} ${!daily_earnings[@]}" | sed 's/ /\n/g' | sort -n | uniq | while read key
do
echo "日付: ${key}, 売上: ${daily_earnings[${key}]}, コスト: ${daily_costs[${key}]}"
done
実行結果
日付: 20240101, 売上: 600000, コスト: 200000
日付: 20240102, 売上: , コスト: 400000
日付: 20240103, 売上: 1200000, コスト: 150000
日付: 20240104, 売上: , コスト: 260000
日付: 20240105, 売上: 1800000, コスト: 330000
日付: 20240106, 売上: , コスト: 210000
日付: 20240107, 売上: 2600000, コスト: 500000
日付: 20240108, 売上: , コスト: 1000000
日付: 20240109, 売上: 3300000, コスト:
日付: 20240110, 売上: 900000, コスト:
日付: 20240112, 売上: 900000, コスト:
日付: 20240114, 売上: 1500000, コスト:
おわりに
連想配列は便利なのでいっぱい使いそう(小並感)