本記事を投稿する背景
集合演算のやり方自体はいろんな方がすでに書いていまして(下記リンク)、すでに本記事と同様のブログエントリもある (Bashで配列の積集合・差集合を求める) のですが、もう少しエレガントにやれてるかなぁ、と思ったので投稿します。
コマンドラインで集合演算
[uniqコマンドを使って、論理和・論理積・排他的論理和・差集合を得る方法]
(https://kunst1080.hatenablog.com/entry/2015/01/25/011158)
方法
別に難しいことはなく、sort にパイプで渡す前の引数の出力をprintf
で行い、引数は位置パラメータ$@
で展開する、というだけです。
set_operations.sh
#!/bin/bash
# 和集合
union() {
printf '%s\n' $@ | sort | uniq
}
# 積集合
intersection() {
printf '%s\n' $@ | sort | uniq -d
}
# 差集合 (1番目の引数 - 2番目の引数)
difference() {
(printf '%s\n' $@ | sort -u; printf '%s\n' ${2}) | sort | uniq -u
}
##################################################################
array1=("1" "2" "3" "7")
array2=("1" "2" "4" "5" "6")
echo "array1: (${array1[@]})"
echo "array2: (${array2[@]})"
union_array=(`union "${array1[*]}" "${array2[*]}"`)
echo "union"
echo ${union_array[@]}
intersection_array=(`intersection "${array1[*]}" "${array2[*]}"`)
echo "intersection"
echo ${intersection_array[@]}
difference_array1=(`difference "${array1[*]}" "${array2[*]}"`)
echo "difference (array1 - array2)"
echo ${difference_array1[@]}
difference_array2=(`difference "${array2[*]}" "${array1[*]}"`)
echo "difference (array2 - array1)"
echo ${difference_array2[@]}
実行時出力
array1: (1 2 3 7)
array2: (1 2 4 5 6)
union
1 2 3 4 5 6 7
intersection
1 2
difference (array1 - array2)
3 7
difference (array2 - array1)
4 5 6
この方法のメリット
書き方がスッキリしていて、コードの見通しが良いかと思います。
実行速度のベンチマークは行っていないので、処理速度の評価は不明です。