• ベストアンサー

配列に複数の値があるか簡潔に判断する方法

hairetu = [1,2,3,4,5] という配列があった時 3と4が含まれているかを判断するには if hairetu.include?(3) && hairetu.include?(4)  p "3と4が含まれている" end と書けばよいのですが 条件が増えたら、見にくくなってしまいます。 そういった理由で if hairetu.include?(3,4) や if hairetu.include?(3 or 4) という具合に、短く書く方法があれば ご教授お願い致します。

  • Ruby
  • 回答数5
  • ありがとう数6

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

  • ベストアンサー
回答No.4

この場合はArray#-が単純で良いと思います。 ([3, 4] - hairetu).empty?

hourensan
質問者

お礼

MillenniuM 様 回答ありがとうございます。 とてもシンプルで、分かりやすいので これを利用させて頂こうと思います。 配列の引き算が出来るのは初めて知りました。 引き算を利用した、素晴らしい発想だと思いました。 お忙しい中、ありがとうございました。

その他の回答 (4)

  • sholmes
  • ベストアンサー率81% (89/109)
回答No.5

# ANo4さんへ おぉなるほど、集合演算でも「-」を使うと今回のケースが綺麗に解決できるんですね・・・思いつきませんでした。 合致判定を Array#include? に依らないのであれば、これがスマートだと思います。 Array#include? は「==」に依存しますが、Array#-は「eql?」に依存する為、動きが異なります。 組み込みクラスでわかりやすいのはFloatが混じった時でしょうか。 http://codepad.org/fqyFSGRK

hourensan
質問者

お礼

sholmes様 補足説明ありがとうございます。 小数点がある場合は、注意が必要なのですね。 大変参考になりました。 お忙しい中、ありがとうございました。

  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.3

重複をどう扱いたいかわからんけど、何も考えない策としては sub = [1, 1, 3] sup = [4, 3, 1, 2, 1] sup.permutation(sub.size).include?(sub) とか。

hourensan
質問者

お礼

koko_u_u様 回答ありがとうございます。 大変参考になりました。 お忙しい中、ありがとうございました。

  • sholmes
  • ベストアンサー率81% (89/109)
回答No.2

そのまま実現している組み込みメソッドは、ちょっと思い当たりませんでした。 自分なら多分、 Enumerable#all? を使ってこんな感じの対処をするかなとは思います。 https://ideone.com/o1plX <おまけ> ANo.1さんへ 集合演算とempty?やany?だけだと、こんな感じの時に困りませんか? # OK p [3, 4] & [1, 2, 3, 4, 5] p [3, 4] & [1, 2, 5] # NG p [3, 4] & [1, 2, 3, 5] 最後に要素数のチェックを入れた方が良いかもしれません。

hourensan
質問者

お礼

sholmes様 回答ありがとうございます。 見た目的にシンプルになりますが 回答NO.4の配列の引き算を利用した方が 分かりやすい気がしましたので そちらを使わせて頂こうと思います。 しかしながら、この方法も 準備さえしておけば、便利使えると思いますので 何かに応用させて頂こうと思います。 ありがとうございました。

回答No.1

ご教示… @ary1 & @ary2 で共通要素が取り出されます。 unless (@ary1 & @ary2).empty? などのようにしてみてはいかがでしょうか。 unlessが嫌なら if (@ary1 & @ary2).size > 0

hourensan
質問者

お礼

Ma-yan_bh1011様 回答ありがとうございます。 大変参考になりました。 お忙しい中、ありがとうございました。

関連するQ&A

  • 配列の並びかえごにFor文使用

    いつもお世話になっております。 今回、配列の要素数に応じて順番を並び替へ、要素数の多いのから少ないものへのforループに挑戦することにしたのですがルーチンが思い浮かばず投稿させていただきました。 DBから 条件1で検索し、その条件でヒットしたid列の値を$hairetu1に格納しております。 条件2で検索し、その条件でヒットしたid列の値を$hairetu2に格納しております。 条件3で検索し、その条件でヒットしたid列の値を$hairetu3に格納しております。 条件4で検索し、その条件でヒットしたid列の値を$hairetu4に格納しております。 条件5で検索し、その条件でヒットしたid列の値を$hairetu5に格納しております。 最大5つの条件で検索できるようにしております。($hairetu変数は全て配列変数として使用しております) 条件1で検索した再に、$hairetu1には、1,2,4という値(id値)が入っており、 条件2で検索した再には、$hairetu2に、1,4という値が入っています。 条件3で検索した再には、$hairetu3に、1,2,3,4という値が入っています。 条件4で検索した再には、$hairetu4に、9999という値が入っています。 条件3で検索した再には、$hairetu5に、1,2という値が入っています。 ※各条件で検索した際に、ヒットしたid数が0の場合、nullが入らないように初期化の時点で9999をセットしております。$hairetu=array(9999); 今回、[条件1 and 条件2 and 条件3 and 条件4 and 条件5] の結果、1と2を最終的に$result_hairetuに格納したいのです。 考えた方法は、 For(i){ for(j){ for(k){ for(l){for(m){ if(hairetu[i]==hairetu[j] && hairetu[i]==hairetu[k]・・・,hairetu[l] ==hairetu[m]){array_push($result_hairetu,hairetu[i])}}}}}} ※i・・・ (i=0;i<count(hairetu1);i++) という方法で、5つのfor文でループし、ifで比較し同じであればresult_hairetuに格納するという手法をとろうとしたのですが、条件2で検索した結果が、1,2の二つであるため、二つ目のfor文を二回走ったところで抜けてしまい処理が途中で終わってしまいます。 途中で抜けるのを防ぐために以下のように配列を並び替えて、 For分で使用するという流れを作りたいのです。 また、今回、hairetu2と5の要素数が同じなのときはどのようにセットしたらよいかもわかりません。要素数が同じである場合はどちらが先でもかまいません。 for(hairetu4){for(hairetu2){for(hairetu5){for(hairetu1){for(hairetu3)}}}} このループの作り方がわかる方がいらっしゃいましたらご教授のほうお願いできないでしょうか?よろしくお願いします。

    • ベストアンサー
    • PHP
  • 2次元配列から条件抽出した要素の操作

    ある2次元配列から条件に合う要素だけ抜き出し、 抜き出した要素でまた2次元配列を作りたいのですがうまくいきません。 ary=[[3,7,5,6,],[4,7,3,9],[2,5,3,7],[8,1,4,3]] ary.each{|x| if x[1]>3 p x end } というかんじで条件抽出しているのですが、 ここで得た出力をまた [[4,7,3,9],[8,1,4,3]] というような2次元配列にしたいのですがやりかたがわかりません。

  • 関数のパラメータを配列に格納したいのですが

    #include<stdio.h> #include<stdlib.h> int func(int, int, int, int); int main(void) { int a = 3, b = 4, c = 5, d = 6; int sum; sum = func(a, b, c, d); printf("合計は%dです。\n", sum); return EXIT_SUCCESS; } int func(int m, int n, int o, int p) { int Hairetu[4]; int Sum = 0; int i; /* ここで、Hairetuにm, n, o, pを格納したい */ for(i=0; i<4; i++) Sum += Hairetu[i]; return Sum; } 例えばこのようなプログラムがあった時、m, n, o, pの値をHairetuに格納するには、どのようにすればよいのでしょうか。 分かりにくい文章ですが、どうかよろしくお願い致します。

  • VBAの配列の格納について

    エクセルのVBAで、セルのデータを配列に格納するスピードを向上したいと思います。 例えば、A1~A10000のセルにデータを書き出す場合、 For 行番号 = 1 To 10000 Cells(行番号, 1).Value = 1 Next よりも、一旦、配列に書き込んだ後、一気にセルに書き込んだ方法が早いのですが、 For 行番号 = 1 To 10000 HAIRETU(行番号, 1) = 1 Next Range("A1:A10000").Value = HAIRETU() 今度は、A1~A10000に書き込んだデータを、再度、配列に格納する場合、 For 行番号 = 1 To 10000 HAIRETU(行番号, 1) = Cells(行番号, 1).Value Next とすると時間がかかるので、 HAIRETU() = Range("A1:A10000").Value というような処理をしたいのですが、うまくいきません。 よい方法がありましたら、ご教授ください。 よろしくお願いします。

  • 空の配列を示す方法

    Flash8を使用して、ActionScript2を書いています。 if文を用いて、「変数my_array(配列)が空の配列でない場合は~」 という条件分岐を書きたいのですが、 空の配列を示す方法がわかりません。 var my_array:Array = new Array(); とした上で、 if (my_array == null) { trace("null"); } else { trace("違う"); } と書いて調べてみたのですが、 nullでもundefinedでも""でも[]でも「違う」と表示されてしまいます。 「空の配列でない場合」という条件を書く方法はあるでしょうか?

    • ベストアンサー
    • Flash
  • c言語の配列操作

    c言語で、hairetu[8][8]があったとして、その中でいくつかの中に1が入っていて、そのほかは0が入っているとします。 0 1 2 3 4 5 6 7 0|1 0 0 0 1 1 1 0 1|1 0 0 0 0 0 0 1 2|0 1 1 0 1 0 1 1 3|・・・・・・・・・・・・ 4|・・・・・・・・・・・・ 5| 6|・・・・・・・・・・・・ 7|0 1 1 0 0 0 0 1 という具合です。 そのとき、ランダムで1を1箇所しかない状態にしたいのですが、 自分が考えた方法だと無駄が多いので、もっとスマートな方法はないかと思い質問させてもらいました。基本的な質問なのですがよろしくお願いします。 以下自分が考えた方法 [64][2]の配列を作成し、上記の[8][8]の配列をfor文で解析し、1が入ってるところの番号を配列[64][2]に格納する。 乱数を使い、ひとつだけ選択する。

  • 配列関数を教えてください

    セル"O1"(オー列1行目)に =IF(OR(LEFT(C1,4)="0004",LEFT(C1,4)="0010",LEFT(C1,4)="0044",LEFT(C1,4)="0061"),"OK","") と入れています。 C列の先頭4バイトが 0004、0010、0044、0061 の時に「OK」を返したいのです。 今後、この判定数字が増えたり減ったりするので どこかに置いておいてそこを参照する形式に変えたいです。 配列を使えば何とかなると思うのですが、 どうすればよいのですか? 置く場所は P2以降の2行目です。 P2に0004 Q2に0010 R2に0044 S2に0061 ・ ・ ・ Z2 といった具合です Z2 まで入ることを前提に教えてください。

  • VBAでの実現方法を教えて下さい

    VBA初心者です。 引数として「日付from(YYYYMM)、日付to(YYYYMM)、間隔」を渡し、戻り値として配列を受け取るプログラミングを考えています。 既存関数などを利用して、実現したいのですが、実現方法がわかりません。 有識者の方、ご教授頂けないでしょうか。 (例)引数「200701(string), 200712(string), 3(integer)」 ⇒戻り値 hairetu(0,0)="200701" hairetu(0,1)="200703" hairetu(1,0)="200704" hairetu(1,1)="200706" hairetu(2,0)="200707" hairetu(2,1)="200709" hairetu(3,0)="200710" hairetu(3,1)="200712"

  • ストアドの戻り値(配列)について

    ストアドをコールして配列型の戻り値を取得したいのですが、 エラーが出てしまい原因が分かりません。 どなたかご教授頂けないでしょうか? ★PL/SQL★ CREATE OR REPLACE TYPE TBL_NUM10 AS VARRAY(10) OF NUMBER(10); CREATE OR REPLACE PACKAGE TEST_PKG IS TYPE TBL_NUM10 IS VARRAY(10) OF NUMBER(10); PROCEDURE HAIRETU(O_CNT OUT TBL_NUM10); END TEST_PKG; / CREATE OR REPLACE PACKAGE BODY TEST_PKG IS PROCEDURE HAIRETU(O_CNT OUT TBL_NUM10) IS TMP_CNT TBL_NUM10; BEGIN TMP_CNT := TBL_NUM10(0,0,0,0,0,0,0,0,0,0); TMP_CNT(1) := 1; TMP_CNT(2) := 2; TMP_CNT(3) := 3; O_CNT := TMP_CNT; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLERRM); END HAIRETU; END TEST_PKG; / DECLARE O_CNT TBL_NUM10; BEGIN TEST_PKG.HAIRETU(O_CNT); DBMS_OUTPUT.PUT_LINE(O_CNT(1)); DBMS_OUTPUT.PUT_LINE(O_CNT(2)); DBMS_OUTPUT.PUT_LINE(O_CNT(3)); END; / ★実行結果★ SQL実行中に以下のエラーが発生しました。 ORA-06550: 行4、列4: PLS-00306: 'HAIRETU'の呼出しで、引数の数または型が正しくありません。 ORA-06550: 行4、列4: PL/SQL: Statement ignored よろしくお願いします。

  • 配列の要素を結合する方法

    すごく基本的なことで恥ずかしいのですが、 条件を満たす配列の要素を結合し、元の配列に返す方法がわかりません。 foreach $aa (@aa) { if ($aa =~ /-/){ } } とまでは考えたのですが・・・ どなたかお分かりの方、よろしくおねがいします。

    • ベストアンサー
    • Perl

専門家に質問してみよう