Dahil etmenin tersi var mı? Ruby Arrays için mi?


190

Kodumda şu mantık var:

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

@playersbir dizidir. Önlemek için bir yöntem var mı !?

İdeal olarak, bu pasaj şöyle olacaktır:

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

1
olan dogeçerli yakut? bir hata alıyorum syntax error, unexpected end-of-input(kaldırırsam çalışır do)
maxymoo 17:18

Bir dizi ile kümeyi arama kriterleri için stackoverflow.com/a/60404934/128421 adresine bakın .
Tin Man

Yanıtlar:


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

ActiveSupport ekler exclude?yöntemi için Array, Hashve String. Bu saf Ruby değil, bir sürü rubyist tarafından kullanılıyor.

Kaynak: Aktif Destek Çekirdek Uzantıları (Ray Kılavuzları)



3
Küçük açıklama: AS Enumerable'a ekler, böylece Enumerable içeren tüm sınıflarla kullanabilirsiniz. Hash ile bile. :)
user2422869

1
Bu yeşil işaretli olmalıdır
etlds

Yöntem artık Rails 4.2.3'e (ve muhtemelen daha önce) otomatik olarak yüklenmiyor, yapmanız gerekenlerrequire 'active_support/core_ext/enumerable'
Dennis

96

Hadi bakalım:

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

Benzer teknikler hakkında daha fazla bilgi için Ruby Stil Kılavuzuna bakabilirsiniz .


Stil rehberi için oy verin. Sadece ihtiyacım olan okuma materyali.
justnorris

1
bir ifade için okunabilir. Eğer birçoğu daha sonra olumsuzluk kullanın! veya ruby ​​dizi sınıfına kendi yönteminizi ekleyin.
Renars Sirotins

3
Bunu hariç tutmayı mı tercih ediyorsunuz? saf Ruby olduğu için cevap ver.
dscher

1
Ancak bileşik bir durumla çalışırken hala garip. if flag unless @players.include?(p.name)gariptir ve if flag && !@players.include?(p.name)olumsuzlama kullanır.
gabe

1
İken iflet sadece truekoşulunu geçmek unlessgeçmesine izin verir falseve nil. Bu bazen hataları bulmakta zorlanır. Bu yüzden tercih ediyorumexclude?
ToTenMilan

12

Aşağıdakiler nasıl olur:

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

Dostum, cevapların bu siteye girme hızı ile, iyi ole kayırmacılığı olmadan ün kazanıp kazanamayacağımı bilmiyorum! :-D Stil Rehberi bağlantısı hoş bir dokunuş.
ilasno

2
Hızlı olmakla ilgili değil. Kapsamlı olmakla ilgilidir. (Buldum) =)
Charles Caldwell

11

Sadece Ruby'ye bakarken:

TL; DR

Karşılaştırma için none?bir blok geçirerek kullanın ==:

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

Array#include?bir bağımsız değişkeni kabul eder ==ve dizideki her bir öğeyi denetlemek için kullanır :

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

Enumerable#none?bir argümanı da kabul edebilir, bu durumda ===karşılaştırma için kullanır . Karşıt davranışı elde etmek include?için parametreyi atlıyoruz ==ve karşılaştırma için kullanarak bir blok geçiriyoruz.

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

Yukarıdaki örnekte aslında şunları kullanabiliriz:

player.none?(7)
 #=> true

Çünkü Integer#==ve Integer#===eşdeğerdir. Ancak şunu düşünün:

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

none?falseçünkü döner Integer === 1 #=> true. Ama gerçekten yasal bir notinclude?yöntem geri dönmeli true. Daha önce yaptığımız gibi:

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

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

Tamam, ama cidden, sürece işe yaramaz.


1
1 unlesssnippet'la 's ok gösterdi ama durum daha karmaşık olabilir. Bu olumsuzlanmış yöntemlere sahip olmanın kullanışlı olduğunu düşünüyorum, daha açıklayıcı kodlara izin veriyorlar.
tokland


1

Kullana bilirmisin:

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

unlesskarşıttır ifya da kullanabilirsiniz reject.

You can rejectnot-Gerekli elemanlar:

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

sonuçları aldıktan sonra uygulamanızı yapabilirsiniz.


0

Kullanılması unlesstek olan tablolar için gayet include?Eğer birinde şeyin dahil kontrol gerektiğinde, örneğin, maddeleri fakat Arrayancak bir başkasında, kullanımı include?ile exclude?çok dostça.

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

Ancak dizzy42'nin yukarıda söylediği gibi, exclude?ActiveSupport kullanımı


Sadece Active Support'un Temel Uzantılarının kullanılmasını gerektirir. guides.rubyonrails.org/v3.2/…
Tin Man

0

Bunun gibi bir şey deneyin:

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

0

Bunu deneyin, saf Ruby, bu yüzden herhangi bir çevre çerçevesi eklemenize gerek yok

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

Birkaç gün boyunca benzer bir mantıkla mücadele ediyordum ve birkaç forum ve soru-cevap panosunu az boşuna kontrol ettikten sonra, çözüm aslında oldukça basitti.


0

Bunu kendim için aradım, buldum ve sonra bir çözüm buldum. İnsanlar kafa karıştırıcı yöntemler ve belirli durumlarda çalışmayan ya da hiç çalışmayan bazı yöntemler kullanıyorlar.

Bunun 6 yıl önce yayınlandığını düşünerek artık çok geç olduğunu biliyorum, ancak umarım gelecekteki ziyaretçiler bunu bulur (ve umarım kodlarını temizleyebilirler.)

Basit çözüm:

if not @players.include?(p.name) do
  ....
end
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.