インクルードの反対はありますか?Ruby配列の場合?


190

私のコードには次のロジックがあります:

if !@players.include?(p.name)
  ...
end

@players配列です。回避できる方法はあり!ますか?

理想的には、このスニペットは次のようになります。

if @players.does_not_include?(p.name)
  ...
end

1
あるdo有効なルビーは?エラーが発生しますsyntax error, unexpected end-of-input(削除すると機能しますdo
maxymoo 2018

配列とセットを検索するためのベンチマークについては、stackoverflow.com / a / 60404934/128421を参照してください。
ティンマン

回答:


369
if @players.exclude?(p.name)
    ...
end

activesupportのは、追加exclude?する方法をArrayHashString。これは純粋なRubyではありませんが、多くのルビイストが使用しています。

出典:Active Support Core Extensions(Rails Guides)



3
マイナーリマーク:ASはそれをEnumerableに追加するため、Enumerableを含むすべてのクラスで使用できます。ハッシュでも。:)
user2422869

1
これは緑色にチェックされているはずです
etlds

メソッドはRails 4.2.3(およびおそらく以前のバージョン)では自動ロードされなくなったため、次の操作を行う必要がありますrequire 'active_support/core_ext/enumerable'
Dennis

96

どうぞ:

unless @players.include?(p.name)
  ...
end

同様の手法の詳細については、Rubyスタイルガイドをご覧ください。


スタイルガイドに賛成票を投じます。必要な資料だけ。
justnorris 2013

1
1つのステートメントで読み取り可能。多くの場合、negateを使用する方が良いです。または独自のメソッドをruby配列クラスに追加します。
Renars Sirotins

3
これを除外よりも優先しますか?純粋なRubyなので答えてください。
dscher

1
しかし、複合条件で作業するときはまだ変です。if flag unless @players.include?(p.name)ぎこちなく、if flag && !@players.include?(p.name)否定を使用します。
gabe

1
一方でifLETが唯一のtrue条件に合格し、unless合格することができますfalsenil。これにより、バグの発見が困難になることがあります。したがって、私は好むexclude?
ToTenMilan '24年

12

次はどうですか:

unless @players.include?(p.name)
  ....
end

このサイトで答えが届く速さで、グレートネポティズムなしに評判を得ることができるかどうかわかりません!:-Dスタイルガイドのリンクはいい感じです。
ilasno 2012

2
速いということではありません。それは徹底することです。(見つけました)=)
Charles Caldwell

11

Rubyのみを見る:

TL; DR

使用none?してそれをブロックを渡す==比較のために:

[1, 2].include?(1)
  #=> true
[1, 2].none? { |n| 1 == n  }
  #=> false

Array#include?1つの引数を受け入れ==、配列内の各要素に対してチェックするために使用します。

player = [1, 2, 3]
player.include?(1)
 #=> true

Enumerable#none?また===、比較に使用する1つの引数を受け入れることもできます。反対の動作を得るにはinclude?、パラメーターを省略し==て、比較に使用するブロックに渡します。

player.none? { |n| 7 == n }
 #=> true 
!player.include?(7)    #notice the '!'
 #=> true

上記の例では、実際に使用できます。

player.none?(7)
 #=> true

Integer#==Integer#===は同等であるためです。しかし考慮してください:

player.include?(Integer)
 #=> false
player.none?(Integer)
 #=> false

none?falseので戻りますInteger === 1 #=> true。しかし、実際には正当なnotinclude?メソッドが返すべきtrueです。前と同じように:

player.none? { |e| Integer == e  }
 #=> true

7
module Enumerable
  def does_not_include?(item)
    !include?(item)
  end
end

わかりましたが、真剣に、はうまくいきません。


1
+1 unlessスニペットが表示されていても問題ありませんが、条件はより複雑になる可能性があります。これらの否定されたメソッドがあると便利だと思います。それらはより宣言的なコードを許可します。
tokland 2012


1

使える:

unless @players.include?(p.name) do
...
end

unlessはの反対if、またはを使用できますreject

することはできrejectません-必須要素:

@players.reject{|x| x==p.name}

結果を取得した後、実装を行うことができます。


0

unless単一のinclude?句を含むステートメントの使用は問題ありませんが、たとえば、あるものに含まれてArrayいて別のものには含まれていないことを確認する必要がある場合、include?with の使用exclude?は非常にわかりやすくなっています。

if @players.include? && @spectators.exclude? do
  ....
end

しかしdizzy42が上で述べたように、の使用にexclude?はActiveSupport が必要です


Active Supportのコア拡張機能を使用する必要があるだけです。guides.rubyonrails.org/v3.2/...
ブリキ男

0

次のようなものを試してください:

@players.include?(p.name) ? false : true

0

これを試してください、それは純粋なRubyなので、周辺フレームワークを追加する必要はありません

if @players.include?(p.name) == false do 
  ...
end

私は数日間同様のロジックで苦労していましたが、いくつかのフォーラムとQ&Aボードをチェックしてほとんど役に立たなかった後、ソリューションは実際にはかなり単純であることがわかりました。


0

私はこれを自分で探していて、これを見つけて、解決策を見つけました。人々は混乱を招く方法と、特定の状況でまったく機能しないかまったく機能しないいくつかの方法を使用しています。

これが6年前に投稿されたことを考えると、今では手遅れであることがわかっていますが、うまくいけば、将来の訪問者がこれを見つけます(そしてうまくいけば、コードをクリーンアップできます)。

シンプルなソリューション:

if not @players.include?(p.name) do
  ....
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.