• ベストアンサー

二つの配列から、同じ値のもの以外を他の配列に入れたい。

二つの配列から、同じ値のもの以外を他の配列に入れたい。 @tmp = ('1','2','3','4','5'); @tmp2 = ('1','3'); ↓ @tmp3 = ('2','4','5'); 重複を除くの方法はあったのですが、 この場合は、逆の結果が欲しいです。 上記のような結果が欲しいのですが、 うまくできませんでした。 どなたかご伝授いただけないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

@wk { @tmp } = (); #tmpの要素でハッシュを作る delete @wk { @tmp2 }; #tmp2の要素を削除する @tmp3 = keys %wk;

sara555
質問者

お礼

回答有難うございました。 今回は、教えていただいた方法で うまくできました。 早い回答だったので、すぐに 解決できました。本当に有難うございました。

その他の回答 (3)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

#3の方のご指摘の通りです。勘違いした回答をしてしまいました。 回答はでてますけど、書いときます。 for $x (@tmp, @tmp2) { $count{ $x }++; } #要素をカウントする、元の配列自体に重複する要素があるとダメ for $x (keys %count){ push @tmp3,$x if $count{$x} == 1 }

sara555
質問者

お礼

今回は、NO.1の回答で、できました。 他の場合の処理も考えていただいて、 連想配列の勉強もしないといけないな と思いました。有難うございました。

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.3

質問の例では、@tmp2 の要素が全て @tmp に含まれているので No.1、2 の回答でも問題ありませんが、命題からすると、@tmp2 にのみ存在する要素があった場合には、それも @tmp3 に入れなければならないように思いますがどうでしょうか?(No.1、2 では入りません。) 下記のスクリプトはその点も考慮してありますが、「@tmp2 だけに存在する要素などない」という場合は、No.1 や 2 の回答の方が効率がよいです。   %check = ();    # 重複チェック用ハッシュを初期化   @tmp3 = grep !--$check{$_}, grep !$check{$_}++, @tmp, @tmp2; 多用する場合は関数化するとよいでしょう。   sub list_xor {     my %check;     grep !--$check{$_}, grep !$check{$_}++, @_;   }   @tmp3 = list_xor(@tmp, @tmp2); ※スクリプトをコピーする場合は、全角空白をタブなどに置換して下さい。

sara555
質問者

お礼

失礼しました。 %check = (); にせず、@check=();として いました。 回答有難うございました。

sara555
質問者

補足

回答有難うございます。今回は、 @tmp2 にのみ存在する要素があった場合の処理は、 必要ではなかったので、NO1さんの回答で うまくできました。このような @tmp2 にのみ存在する時の処理も学べて、 嬉しかったです。有難うございました。 良かったら、1つ回答していただきたいのですが、 for($a=0; $a<2; $a++){  %wk = ();    # 重複チェック用ハッシュを初期化 } したところ、うまく削除できず、 おかしな値になりました。 何がいけないのでしょうか? 今は、 for($a=0; $a<2; $a++){  %wk = ();    # 重複チェック用ハッシュを初期化  %wk1 = ();    # 重複チェック用ハッシュを初期化 } 配列を別名にしました。

  • t140
  • ベストアンサー率39% (59/150)
回答No.2

@del{@tmp2}= (); @tmp3= grep(!exists $del{$_}, @tmp);

sara555
質問者

お礼

回答有難うございました。 次回はこの方法も使わせていただきます。 色々な方法があるのですね。 勉強になりました。

関連するQ&A