6

配列に要素が含まれているかどうかを確認するためのこのクールな Bash 関数を見つけました。

CONTAINS_ELEMENT(){
  local e
  for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
  return 1
}

使用例を次に示します。

if CONTAINS_ELEMENT $element "${array[@]}"; then
... 
fi

私の質問はこれです:配列内の値が他の配列内の値と等しいかどうかをチェックできるように、この関数を書き直す方法はありますか?

4

4 に答える 4

3

修正済み#3

以下のコードを試してください。ArrContains2 つの配列の名前である 2 つの引数を取ります。から一時的なハッシュを作成し、のlArr1要素がlArr2ハッシュに含まれているかどうかを確認します。このようにして、埋め込まれたforループを回避できます。

#!/usr/bin/bash

ArrContains(){
  local lArr1 lArr2
  declare -A tmp
  eval lArr1=("\"\${$1[@]}\"")
  eval lArr2=("\"\${$2[@]}\"")
  for i in "${lArr1[@]}";{ ((++tmp['$i']));}
  for i in "${lArr2[@]}";{ [ -n "${tmp[$i]}" ] && return 0;}
  return 1
}

arr1=("a b" b c)
arr2=(x 'b c' e)
arr3=(q a\ b y)
ArrContains arr1 arr2 && echo Contains arr1 arr2
ArrContains arr1 arr3 && echo Contains arr1 arr3

出力:

Contains arr1 arr3

別の方法として、区切り文字を定義して最初のハッシュを連結することもできます。次に、一致するSEPitemSEP文字列を検索します。

ArrContainsRe(){
  local lArr1 lArr2 tmp
  eval lArr1=("\"\${$1[@]}\"")
  printf -v tmp ",%s" "${lArr1[@]}";
  tmp="$tmp,"
  eval lArr2=("\"\${$2[@]}\"")
  for i in "${lArr2[@]}";{ [[ $tmp =~ ,$i, ]] && return 0;}
  return 1
}
...
ArrContainsRe arr1 arr2 && echo ContainsRe arr1 arr2
ArrContainsRe arr1 arr3 && echo ContainsRe arr1 arr3

出力:

ContainsRe arr1 arr3
于 2013-06-11T11:09:46.687 に答える
0

上記のリンクを見ると、必要なことをほぼ実行するソリューションにたどり着きましたが、完全ではありません。

parameters=($1 $2 $3 $4)
arg1=(h help -h --help)

PARAMETERS(){
pr1=" $parameters[@]} "
for item in ${@:1}; do
  if [[ $pr1 =~ " $item " ]]; then
    return 0
  else
    return 1
  fi
done
}

if PARAMETERS "${arg1[@]}"; then
  echo "It works!"
else
  echo "Nope, still not working..."
fi

このコードは、パラメーター「h」を渡すと機能しますが、配列内の他のパラメーターを渡すと機能しません (-h --help help)。ここでばかげた間違いをしている場合は申し訳ありません.bashスクリプトに関しては、私はやや無知です:)

于 2013-06-11T12:38:31.997 に答える
-1

これはそれを行う必要があります:

any_overlap() {
    for e1 in "${array1[@]}"
    do
        for e2 in "${array2[@]}"
        do
            if [[ "$e1" = "$e2" ]]
            then
                return 0
            fi
        done
    done
    return 1
}

テスト セッション:

$ array1=(foo bar baz) array2=(ban bat bar) && any_overlap; echo $?
0
$ array1=(foo bar baz) array2=(ban bat) && any_overlap; echo $?
1
$ array1=() array2=() && any_overlap; echo $?
1

もちろん、配列がソートされているか、配列要素に空白が含まれていない場合は、より高速な方法があります。

于 2013-06-11T10:53:59.530 に答える