Yaqutda bir sıra bir dəyəri olub olmadığını yoxlayın

Mən 'Dog' və bir sıra ['Cat', 'Dog', 'Bird'] .

Kaydırmadan bir dizidə mövcud olub olmadığını necə yoxlamaq olar? Bir dəyərin olmadığını yoxlamaq üçün asan bir yol varmı?

1165
31 дек. user211662 tərəfindən təyin 31 dekabr 2009-12-31 20:49 '10 at 08:49 PM 2009-12-31 20:49
@ 24 cavab

include? :

 >> ['Cat', 'Dog', 'Bird'].include? 'Dog' => true 
1745
31 дек. Cavab Brian Campbell tərəfindən verilir 31 dekabr. 2009-12-31 20:51 '10 at 20:51 2009-12-31 20:51

İçəridə bir in? ActiveSupport (Rails hissəsi) versiyası v3.1-dən @campaterson tərəfindən göstərildiyi kimi. Beləliklə, Rails-də və ya require 'active_support' etdiyiniz halda, yaza bilərsiniz:

 'Unicorn'.in?(['Cat', 'Dog', 'Bird']) # => false 

OTOH, Ruby'də heç bir operator yox #in? Daha əvvəl təklif olunsa da, , Array , Hash , Set , Range daxil olmaqla, bütün Enumerable üçün:

 ['Cat', 'Dog', 'Bird'].include?('Unicorn') # => false 

border=0

Dizinizdə bir çox dəyərə sahib olsanız, hash axtarışı sabit olacaq (yəni, O(1) ), onlar birbaşa (yəni, O(n) ) yoxlanılır. Buna görə, məsələn, dizi sabit olduqda, Set istifadə etmək məsləhətdir. Məsələn:

 require 'set' ALLOWED_METHODS = Set[:to_s, :to_i, :upcase, :downcase # etc ] def foo(what) raise "Not allowed" unless ALLOWED_METHODS.include?(what.to_sym) bar.send(what) end 

Tez test zəngin include? olduğunu göstərir include? Elementdə 10 ədəd Set , ekvivalent Array üzərindən çağırışdan 3,5 dəfə daha sürətli (element tapılmadıqda).

Son yekun qeyd: istifadə edərkən ehtiyatlı olun include? Range , incəliklər var, buna görə sənədə baxın və cover? ilə müqayisə edin cover? ...

213
15 мая '12 в 15:50 2012-05-15 15:50 Marc-André Lafortune -ə 15 may, 2012-ci il saat 15:50 radələrində cavab verib 2012-05-15 15:50

Keçir

 ['Cat', 'Dog', 'Bird'].include?('Dog') 
158
31 дек. Cavab verilir schmitzelburger 31 dekabr. 2009-12-31 20:52 '10 'da 20:52' de 2009-12-31 20:52 'də

Enumerable#include istifadə edin:

 a = %w/Cat Dog Bird/ a.include? 'Dog' 

Və ya, bir neçə sınaq aparılırsa, 1 (hətta include? ) loopdan qurtulub O (n) -dən O (1) -ə getmək olar:

 h = Hash[[a, a].transpose] h['Dog'] 


1. Ümid edirəm ki, bu aydındır, lakin etirazlara etiraz etmək üçün: bəli, bir neçə axtarış, Hash [] və transpose ops profil üstünlük təşkil edir və hər biri O (n).
45
31 дек. Cavab DigitalRoss 31 dekabrdır . 2009-12-31 20:52 '10 'da 20:52' de 2009-12-31 20:52 'də

Bloku yoxlamaq istəyirsinizsə, hər hansı bir cəhd edə bilərsiniz? ya da hamısı.

 %w{ant bear cat}.any? {|word| word.length >= 3} #=> true %w{ant bear cat}.any? {|word| word.length >= 4} #=> true [ nil, true, 99 ].any? #=> true 

Ayrıntılar burada: http://ruby-doc.org/core-1.9.3/Enumerable.html
Mənim ilhamım buradan gəldi: on123.ru.site /questions/10947 / ...

44
20 мая '12 в 12:08 2012-05-20 12:08 Vana 20 May 'da 12:08' də cavab verdi 2012-05-20 12:08

Array#include? lakin bir əhəmiyyətli xəbərdarlıq var: mənbəyə baxarkən, Array#include? bir döngə yerinə yetirir:

 rb_ary_includes(VALUE ary, VALUE item) { long i; for (i=0; i<RARRAY_LEN(ary); i++) { if (rb_equal(RARRAY_AREF(ary, i), item)) { return Qtrue; } } return Qfalse; } 

Döngə olmadan bir sözün varlığını yoxlamaq yolu, diziniz üçün trie yaratmaqdır. Çox trie tətbiqləri var (google "ruby trie"). Bu nümunədə rambling-trie istifadə edəcəyəm:

 a = %w/cat dog bird/ require 'rambling-trie' # if necessary, gem install rambling-trie trie = Rambling::Trie.create { |trie| a.each do |e| trie << e end } 

İndi Array#include? kimi eyni sintaktik sadəlik ilə O(log n) zaman, loop olmadan, sizin sıra müxtəlif sözlər varlığını yoxlamaq üçün hazırıq Array#include? subtrialar Trie#include? istifadə Trie#include? :

 trie.include? 'bird' #=> true trie.include? 'duck' #=> false 
29
10 июня '13 в 19:23 2013-06-10 19:23 Cavab Boris Stitnicky tərəfindən verilir 10 İyun 2013 19:23 2013-06-10 19:23

Ruby bir sıra elementləri axtarmaq üçün 11 üsula malikdir.

Əlavə etmək include?

Yenidən daxil olmaq, bir set yaratmaq və sonra zəng etmək include? və ya member?

Hamısı bunlardır

 array.include?(element) # preferred method array.member?(element) array.to_set.include?(element) array.to_set.member?(element) array.index(element) > 0 array.find_index(element) > 0 array.index { |each| each == element } > 0 array.find_index { |each| each == element } > 0 array.any? { |each| each == element } array.find { |each| each == element } != nil array.detect { |each| each == element } != nil 

Element mövcud olduqda hamısı true işi geri qaytarır.

include? seçim üsuludur. Bir element daxili rb_equal_opt/rb_equal funksiyalarına uyğun olduqda sona çatan bir daxili rb_equal_opt/rb_equal . Təkrar üzvlük dəsti yaratmırsanız, bu, daha səmərəli ola bilməz.

 VALUE rb_ary_includes(VALUE ary, VALUE item) { long i; VALUE e; for (i=0; i<RARRAY_LEN(ary); i++) { e = RARRAY_AREF(ary, i); switch (rb_equal_opt(e, item)) { case Qundef: if (rb_equal(e, item)) return Qtrue; break; case Qtrue: return Qtrue; } } return Qfalse; } 

member? Array sinifində Enumerable bütün elementləri Enumerable olaraq Enumerable edən Enumerable modulundan qeyri-optimallaşdırılmış bir proqram istifadə edir.

 static VALUE member_i(RB_BLOCK_CALL_FUNC_ARGLIST(iter, args)) { struct MEMO *memo = MEMO_CAST(args); if (rb_equal(rb_enum_values_pack(argc, argv), memo->v1)) { MEMO_V2_SET(memo, Qtrue); rb_iter_break(); } return Qnil; } static VALUE enum_member(VALUE obj, VALUE val) { struct MEMO *memo = MEMO_NEW(val, Qfalse, 0); rb_block_call(obj, id_each, 0, 0, member_i, (VALUE)memo); return memo->v2; } 

Ruby koduna çevrilən bu, aşağıdakıları əhatə edir

 def member?(value) memo = [value, false, 0] each_with_object(memo) do |each, memo| if each == memo[0] memo[1] = true break end memo[1] end 

Hər ikisi də include?member? O(n) zaman mürəkkəbliyinə malikdir, çünki hər ikisi gözlənilən dəyərin ilk dəfə baş verməsi üçün bir sıra axtarır.

Biz O(1) giriş müddətini əvvəlcə dizinin hash nümayişini yaratmaq üçün qurmaqdan istifadə edə bilərik. Eyni dizidəki üzvlüyü təkrar yoxlasanız, bu ilkin investisiya tez ödəyir. Set C-də tətbiq edilmir, lakin normal bir Ruby sinifi kimi, O(1) bazasının @hash üçün giriş müddəti dəyərli edir.

Burada Set sinifinin tətbiqi,

 module Enumerable def to_set(klass = Set, *args,  klass.new(self, *args,  end end class Set def initialize(enum = nil,  # :yields: o @hash ||= Hash.new enum.nil? and return if block do_with_enum(enum) { |o| add(block[o]) } else merge(enum) end end def merge(enum) if enum.instance_of?(self.class) @hash.update(enum.instance_variable_get(:@hash)) else do_with_enum(enum) { |o| add(o) } end self end def add(o) @hash[o] = true self end def include?(o) @hash.include?(o) end alias member? include? ... end 

Gördüyünüz kimi, Set sinfi bir daxili @hash örneğini @hash , bütün obyektləri true xəritələrə yerləşdirir və sonra Hash#include? olanları yoxlayır Hash#include? Hash sinifində O(1) giriş saatı ilə həyata keçirilir.

Digər 7 üsulları daha az və daha az təsirli olduğu üçün müzakirə etməyəcəyəm.

Əslində yuxarıda göstərilən yuxarıda 11 O(n) yuxarıda O(n) mürəkkəbliyi ilə daha çox üsullar var, amma ilk matçdakı boşluğu deyil, bütün ardıcıllığı tararken onları siyahıya salmamağa qərar verdim.

Onları istifadə etməyin

 # bad examples array.grep(element).any? array.select { |each| each == element }.size > 0 ... 
27
26 дек. Cavab akuhn 26 dekabrda verilir. 2016-12-26 02:40 '17 'də 2:40' də 2016-12-26 02:40 'da

Əgər sitat vermək istəməsəniz, bunu dizilerle etmək mümkün deyil. Bunun əvəzinə Set istifadə etməlisiniz.

 require 'set' s = Set.new 100.times{|i| s << "foo#{i}"} s.include?("foo99") => true [1,2,3,4,5,6,7,8].to_set.include?(4) => true 

Nəzərdən keçirildiyi kimi, adın nəzərdə tutulduğu kimi, əsas haşiyə yaradır və hər bir hash nöqtəsi yaddaşda müəyyən bir nöqtəyə işarə verən bir yaddaş kartı yaradır, çünki Ruby, maddələr axtarmaq üçün toplanaraq keçməyə ehtiyac yoxdur. Əvvəlki nümunə Hash istifadə edilir:

 fake_array = {} 100.times{|i| fake_array["foo#{i}"] = 1} fake_array.has_key?("foo99") => true 

Dezavantajı ki, Set və hash düymələri yalnız unikal elementləri özündə birləşdirir və bir çox element əlavə edərsəniz, Ruby daha geniş bir əsas sahəyə uyğun yeni bir xəritə qurmaq üçün müəyyən elementlərdən sonra bütün bunları təkrarlamaq məcburiyyətində qalacaq. Daha ətraflı məlumat üçün, MountainWest RubyConf 2014 - Nathan Long-dan bir ev hashında Big O

İşdə bir kriter:

 require 'benchmark' require 'set' array = [] set = Set.new 10_000.times do |i| array << "foo#{i}" set << "foo#{i}" end Benchmark.bm do |x| x.report("array") { 10_000.times { array.include?("foo9999") } } x.report("set ") { 10_000.times { set.include?("foo9999") } } end 

Və nəticələr:

  user system total real array 7.020000 0.000000 7.020000 ( 7.031525) set 0.010000 0.000000 0.010000 ( 0.004816) 
16
29 мая '14 в 22:58 2014-05-29 22:58 cavab Kimmo Lehto tərəfindən 29 May '14 'də 10:58 2014-05-29 22:58 tərəfindən verilir

Bunu etmək üçün başqa bir yoldur: Array # endeks metodunu istifadə edin.

Element elementinin ilk başlanğıc indeksini qaytarır.

Məsələn:

 a = ['cat','dog','horse'] if a.index('dog') puts "dog exists in the array" end 

indeks () də blok qəbul edə bilər.

məsələn

 a = ['cat','dog','horse'] puts a.index {|x| x.match /o/} 

Burada, 'o' hərfini əks etdirən sətrə ilk sözün indeksini qaytarın.

15
02 окт. Cavab zack xu 02 oktyabr tərəfindən verilir . 2013-10-02 20:22 '13 saat 20:22 'da 2013-10-02 20:22

Bunun bir çox yolu var. Bəziləri bunlardır:

 a = [1,2,3,4,5] 2.in? a #=> true 8.in? a #=> false a.member? 1 #=> true a.member? 8 #=> false 
8
29 апр. Cavab 29 apr üzrə sumit verilir . 2016-04-29 13:12 '16 saat 13:12 'də 2016-04-29 13:12

Funny fakt

Bir ifadənin ifadələrində olub olmadığını yoxlamaq üçün * istifadə edə bilərsiniz.

 case element when *array ... else ... end 

Yadda olduğunda kiçik * qeyd edin, bu dizi üçün yoxlayır.

Splat operatorunun adi sehirli davranışı, məsələn, array həqiqətən bir sıra deyilsə, bir element olsa, bu elementə uyğun olacaq.

7
26 дек. Cavab akuhn 26 dekabrda verilir. 2016-12-26 02:48 '17 'da 2:48' də 2016-12-26 02:48 'də

Bu, yalnız varlığını deyil, nə qədər göründüyünü sizə xəbər verəcəkdir:

  a = ['Cat', 'Dog', 'Bird'] a.count("Dog") #=> 1 
5
15 апр. cavab user3245240 15 apr tərəfindən verilir . 2014-04-15 21:29 '14 at 21:29 2014-04-15 21:29

Nə dəyərli olduğuna görə, Ruby sənədləri bu cür suallar üçün gözəl bir qaynaqdır.

Mən də baxdığınız sıra uzunluğunu qeyd etmək istərdim. Metod include? O (n) mürəkkəbliyi ilə xətti axtarış aparacaq və bu, dizinin ölçüsündən asılı olaraq çox çirkin ola bilər.

Böyük (sıralanmış) bir sıra ilə işləsəniz, çox mürəkkəb olmamalı və ən pis vəziyyətdə olan O (log n) bir axtarış alqoritmini yazmağı düşünürəm .

Və ya, Ruby 2.0 istifadə bsearch istifadə edə bilərsiniz.

5
31 июля '13 в 7:04 2013-07-31 07:04 Cavab davissp14 31 iyul 'da 07:04' də verilir 2013-07-31 07:04

Daha çox dəyərlər deməkdirsə ... cəhd edə bilərsiniz:

Misal: Cat və Dog bir dizidəki varsa:

 (['Cat','Dog','Bird']  ['Cat','Dog'] ).size == 2 #or replace 2 with ['Cat','Dog].size 

Bunun əvəzinə:

 ['Cat','Dog','Bird'].member?('Cat') and ['Cat','Dog','Bird'].include?('Dog') 

Qeyd: üzv? və daxil? eynidır.

Bu bir xətt üzrə iş edə bilər!

4
07 апр. Daniel Antonio Nuñez Carhuayo tərəfindən verilmiş cavab 07 Apr 2014-04-07 18:04 '14 at 18:04 2014-04-07 18:04

İçərisindən istifadə etmək istəmiriksə include? Həm də işləyir:

 ['cat','dog','horse'].select{ |x| x == 'dog' }.any? 
3
20 февр. cavab xlemburas 20 feb verilir . 2014-02-20 10:24 '14 da 10:24 2014-02-20 10:24

Bunun əksinə də var!

Serialın [: redaktə: yeniləmə: yaratmaq, göstərmək] ehtimal ki, bütün yeddi ölümcül / yatıştırıcı günahdır.

Və sonra oyuncaq bəzi xətt faktiki hərəkət çəkmək fikir ilə - deyirlər

qardaşım onun profilini yeniləməsini istəyirəm

Həll

 [ :edit, :update, :create, :show ].select{|v| v if "my brother would like me to update his profile".downcase =~ /[,|.| |]#{v.to_s}[,|.| |]/} 
3
15 окт. Cavab walt_die 15 oct verilir . 2012-10-15 17:08 '12 at 17:08 2012-10-15 17:08

Hər hansı bir əsas üçün birdən çox dəyərləri yoxlamaq lazımdırsa, arr hash ə çevirmək və indi O (1)

 arr = ['Cat', 'Dog', 'Bird'] hash = arr.map {|x| [x,true]}.to_h => {"Cat"=>true, "Dog"=>true, "Bird"=>true} hash["Dog"] => true hash["Insect"] => false 

Hash performansı # has_key? #include array ilə müqayisədə ?

 Parametrlər Hash # has_key?  Array # daxildir  Vaxt mürəkkəbliyi O (1) əməliyyatı O (n) əməliyyat  Access Növü hər elementdən yinelerse, Hash [düyməsini] daxil olur hər hansı bir dəyəri qaytarır əsl dəyər döndü Hash # has_key?  zəng edin zəng edin

Bir dəfə yoxlama üçün istifadə etmək include? Bu yaxşıdır

3
28 апр. Cavab verilir aqfaridi 28 apr. 2017-04-28 22:38 '17 saat 10:38 'da 2017-04-28 22:38
 ['Cat', 'Dog', 'Bird'].detect { |x| x == 'Dog'} => "Dog" !['Cat', 'Dog', 'Bird'].detect { |x| x == 'Dog'}.nil? => true 
3
28 нояб. Cavab 28 noyabrda Rahul Patel tərəfindən verilir 2016-11-28 16:43 '16 at 16:43 2016-11-28 16:43

Bu şəkildə necə olur?

2
19 авг. Cavab verilir 19 avqu . 2014-08-19 16:11 '14 at 16:11 2014-08-19 16:11

Dizi üsulunu açmağa çalışmalısınız.

 ['Cat', 'Dog', 'Bird'].include? 'Dog' >>true 

Dizayn üsulları haqqında daha ətraflı məlumat üçün https://ruby-doc.org/core-2.2.0/Array.html ünvanına daxil olun .

0
25 янв. Cavab Foram Thakral tərəfindən verilir. 25 yanvar. 2019-01-25 10:23 '19 da 10:23 PM 2019-01-25 10:23
 array = [ 'Cat', 'Dog', 'Bird' ] array.include?("Dog") 
0
29 нояб. Cavab Matthew Maurice tərəfindən 29 noyabrda verilir. 2016-11-29 07:23 '16 saat 07:23 'də 2016-11-29 07:23

istifadə etmək istəmirsinizsə əvvəlcə bir elementə bir sıra sarın və sonra səpilən element serialın və bükülmüş elementin kəsişməsinə bərabər olub olmadığını yoxlaya bilərsiniz. Bu bərabərlik əsasında məntiqi bir dəyər verir.

 def in_array?(array, item) item = [item] unless item.is_a?(Array) item == array  item end 
0
15 мая '14 в 9:46 2014-05-15 09:46 cavab maye 15 may, 14: 14-da verilir , 2014-05-15 09:46

Bunu etmək üçün başqa bir yoldur:

 arr = ['Cat', 'Dog', 'Bird'] e = 'Dog' present = arr.size != (arr - [e]).size 
0
05 янв. Cavab Wand Maker tərəfindən verilir 05 yanvar. 2016-01-05 10:04 '16 at 10:04 2016-01-05 10:04

hər hansı bir sıra bir element tapmaq üçün bir çox yolu var, lakin ən asan yolu "in"? üsulu

 example: arr = [1,2,3,4] number = 1 puts "yes #{number} is present in arr" if number.in? arr 
-1
17 янв. Abhishek kumar tərəfindən cavabı yanvar 17 2019-01-17 13:03 '19 saat 13:03 'da 2019-01-17 13:03

haqqında digər suallar ya da sual