दिलचस्प पोस्ट
कुछ फ़ील्ड पर डुप्लिकेट ढूंढने के लिए कथन चुनें आईओएस – कैसे तेजी से प्रोग्रामिंग सेगमेंट सेगमेंट करें आईफोन: एनीमेशन के साथ टैब कैसे स्विच करें? MySQL क्वेरी ग्रुप द्वारा दिन / महीना / वर्ष कैसे विंडोज 7 64 बिट पर theano के साथ सेटअप cuDnn क्या गिटौब को आईडी याद है? घातक त्रुटि: 134217728 बाइट्स की मात्रा का अनुमत मेमोरी आकार (CodeIgniter + XML-RPC) @@ पहचान, SCOPE_IDENTITY (), आउटपुट और पिछली पहचान पुनर्प्राप्त करने के अन्य तरीकों Ajax और jquery का उपयोग कर div सामग्री की जगह जावा में नल क्या है? क्रोम डेवलपमेंट टूल: जावास्क्रिप्ट से फाइल अन्य समान वर्गों पर हैंडलर का सर्वोत्तम उपयोग करें एंड्रॉइड: सभी ऐप का साफ़ कैश? निर्भरता वाकर: लापता डीएलएलएस अवधि के साथ चयनित पाठ नोड को लपेटें

जांचें कि क्या रूबी में कोई मान मौजूद है

मेरे पास एक मूल्य 'Dog' और एक सरणी ['Cat', 'Dog', 'Bird']

मैं कैसे जांचूं कि यह बिना सरणी के बिना सरणी में मौजूद है? क्या मूल्य का पता लगाने का कोई आसान तरीका है, और कुछ नहीं?

वेब के समाधान से एकत्रित समाधान "जांचें कि क्या रूबी में कोई मान मौजूद है"

आप include? :

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

एक in? v3.1 के बाद ActiveSupport (रेल का हिस्सा) में विधि , जैसा कि @कंपटटरसन द्वारा बताया गया है। तो रेल के भीतर, या यदि आपको require 'active_support' , तो आप लिख सकते हैं:

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

ओटोह, ऑपरेटर या #in? in कोई नहीं in #in? खुद रूबी में विधि, भले ही यह पहले प्रस्तावित किया गया है, विशेष रूप से यूसुके एंडोह द्वारा रूबी-कोर का एक शीर्ष पायदान सदस्य।

जैसा कि दूसरों के द्वारा बताया गया है, रिवर्स विधि include? Array , Hash , Set , Range सहित सभी Enumerable लिए मौजूद है:

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

ध्यान दें कि यदि आपके सरणी में आपके कई मान हैं, तो वे सभी को एक (यानी O(n) बाद एक की जाँच कर लेगा, जबकि एक हैश के लिए लुकअप निरंतर समय (यानी O(1) ) होगा। इसलिए यदि आप सरणी स्थिर हैं, उदाहरण के लिए, इसके बजाय सेट का उपयोग करने के लिए एक अच्छा विचार है उदाहरण के लिए:

 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 

एक त्वरित परीक्षण से पता चलता है कि बुला include? एक 10 तत्व Set पर समकक्ष Array (यदि तत्व नहीं मिला है) पर कॉल करने से लगभग 3.5x तेज है।

अंतिम समापन नोट: सावधान रहें जब उपयोग include? Range , सूक्ष्मताएं हैं, तो डॉक्टर को देखें और cover? साथ तुलना करें cover?

प्रयत्न

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

Enumerable#include उपयोग करें Enumerable#include :

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

या, अगर बहुत सारे परीक्षण किए जाते हैं, 1 आप पाश से छुटकारा पा सकते हैं (जो भी include? है) और ओ (एन) से ओ (1) तक के साथ जा सकते हैं:

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


1. मुझे उम्मीद है कि यह स्पष्ट है, लेकिन आपत्तियों को दूर करने के लिए: हाँ, केवल कुछ खोजों के लिए, हैश [] और ऑप्स को स्थानांतरित करना प्रोफ़ाइल पर हावी है और प्रत्येक ओ (एन) स्वयं हैं

यदि आप किसी ब्लॉक से चेक करना चाहते हैं, तो आप किसी भी कोशिश कर सकते हैं? या सभी ?.

 %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 

विवरण यहाँ हैं: http://ruby-doc.org/core-1.9.3/Enumerable.html
मेरी प्रेरणा यहाँ से आती है: https://stackoverflow.com/a/10342734/576497

कई जवाबों में Array#include? , लेकिन एक महत्वपूर्ण चेतावनी है: स्रोत को देखते हुए, यहां तक ​​कि Array#include? प्रदर्शन करता है:

 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; } 

लूपिंग के बिना शब्द उपस्थिति का परीक्षण करने का तरीका आपके सरणी के लिए ट्राई का निर्माण कर रहा है। वहाँ कई trie कार्यान्वयन वहाँ बाहर हैं (गूगल "रूबी trie") मैं इस उदाहरण में rambling-trie का प्रयोग करूँगा:

 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 } 

और अब हम आपके सरणी में विभिन्न शब्दों की उपस्थिति को बिना किसी looping के परीक्षण के लिए तैयार हैं, O(log n) समय में, उसी वाक्यविन्यास सादगी के साथ, जैसे Array#include? , सबलाइनर Trie#include? का उपयोग करके Trie#include? :

 trie.include? 'bird' #=> true trie.include? 'duck' #=> false 

यह करने का एक और तरीका है: अर्रे # इंडेक्स विधि का उपयोग करें

यह सरणी में तत्व की पहली घटना का सूचक देता है।

उदाहरण:

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

सूचकांक () एक ब्लॉक भी ले सकता है

उदाहरण के लिए

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

यहां, ऐरे में पहले शब्द का सूचक वापस करें जिसमें 'ओ' वाला अक्षर शामिल है

रूबी में एक सरणी में तत्वों को खोजने के लिए 11 तरीके हैं।

पसंदीदा में include?

या बार-बार पहुंच के लिए, एक सेट बनाना और फिर कॉल करना include? या member?

यहां उन सभी हैं,

 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 

तत्व मौजूद है, तो वे सभी true ईश मूल्य वापस आते हैं।

include? पसंदीदा तरीका है यह आंतरिक रूप से लूप के for सी-भाषा का उपयोग करता है, जब एक तत्व आंतरिक rb_equal_opt/rb_equal फ़ंक्शंस से मेल खाता है। जब तक आप बार-बार सदस्यता जांच के लिए एक सेट नहीं बनाते, तब तक यह अधिक कुशल नहीं हो सकता।

 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 श्रेणी में फिर से परिभाषित नहीं होता है और Enumerable मॉड्यूल से एक अपरिवर्तनीय कार्यान्वयन का उपयोग करता है जो कि सभी तत्वों के माध्यम से शाब्दिक रूप से गणना करता है।

 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; } 

रूबी कोड में अनुवाद किया गया यह निम्नलिखित के बारे में है

 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 

दोनों include? और member? अपेक्षित मूल्य की पहली घटना के लिए दोनों खोज सरणी के बाद से O(n) समय की जटिलता है।

हम एक सेट का उपयोग O(1) पहुंच समय को सरणी के हैश प्रतिनिधित्व को बनाने के लिए पहले कर सकते हैं। यदि आप बार-बार एक ही सरणी पर सदस्यता जांचते हैं तो यह प्रारंभिक निवेश जल्दी से भुगतान कर सकता है। Set सी में कार्यान्वित नहीं किया गया है लेकिन सादे रूबी क्लास के रूप में, अभी भी अंतर्निहित @hash के O(1) एक्सेस का समय इस सार्थक बनाता है।

यहां Set क्लास का कार्यान्वयन है,

 module Enumerable def to_set(klass = Set, *args, &block) klass.new(self, *args, &block) end end class Set def initialize(enum = nil, &block) # :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 

जैसा कि आप देख सकते हैं कि Set क्लास सिर्फ एक आंतरिक @hash उदाहरण बनाता है, सभी ऑब्जेक्ट्स को true पर मैप करता true और फिर @hash Hash#include? का उपयोग करके सदस्यता जांचता है Hash#include? जो O(1) Hash कक्षा में पहुंच के समय O(1) साथ लागू किया गया है।

मैं अन्य 7 विधियों पर चर्चा नहीं करूंगा क्योंकि वे सभी कम कुशल हैं I

वहाँ वास्तव में O(n) ऊपर सूचीबद्ध 11 से परे जटिलता के साथ और भी अधिक तरीकों हैं, लेकिन मैंने पहली बार मैच को तोड़ने के बजाय पूरे सरणी को स्कैन करने के बाद उनकी सूची नहीं दी।

इन का उपयोग न करें,

 # bad examples array.grep(element).any? array.select { |each| each == element }.size > 0 ... 

यदि आप लूप नहीं करना चाहते हैं, तो यह करने के लिए कोई रास्ता नहीं है। इसके बजाय आपको एक सेट का उपयोग करना चाहिए।

 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 

हथेस की तरह आंतरिक रूप से काम करता है, इसलिए रूबी को वस्तुओं को खोजने के लिए संग्रह के माध्यम से लूप की आवश्यकता नहीं होती है, क्योंकि नाम से पता चलता है, चूंकि यह कुंजी का हैश बनाता है और मेमोरी मानचित्र बनाता है ताकि प्रत्येक हॅश पॉइंट मेमोरी में एक निश्चित बिंदु तक हो सके। एक हैश के साथ पिछले उदाहरण:

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

नकारात्मक पक्ष यह है कि सेट और हैश कुंजियों में केवल अनन्य आइटम्स शामिल हो सकते हैं और यदि आप बहुत सारे आइटम जोड़ते हैं, तो रूबी को एक बड़ी कुंजीपटल के लिए एक नया मानचित्र बनाने के लिए निश्चित वस्तुओं की संख्या के बाद पूरे चीज को फिर से करना होगा। इसके बारे में अधिक जानने के लिए, मैं आपको माउंटेनवेस्ट रूबीकॉन्फ़ 2014 को देखने की सलाह देता हूं – नाथन लांग द्वारा होममेड हैश में बिग हे

यहां एक बेंचमार्क है:

 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 

और परिणाम:

  user system total real array 7.020000 0.000000 7.020000 ( 7.031525) set 0.010000 0.000000 0.010000 ( 0.004816) 

यह पूरा करने के कई तरीके हैं। उनमें से कुछ इस प्रकार हैं:

 a = [1,2,3,4,5] 2.in? a #=> true 8.in? a #=> false a.member? 1 #=> true a.member? 8 #=> false 

यह आपको न केवल यह बताएगा कि यह मौजूद है लेकिन यह कितनी बार प्रकट होता है:

  a = ['Cat', 'Dog', 'Bird'] a.count("Dog") #=> 1 

इसके लिए क्या है, रूबी डॉक्स इन प्रकार के सवालों के लिए एक अद्भुत संसाधन हैं

मैं उस सरणी की लंबाई का भी ध्यान रखूंगा जो आप खोज रहे हैं। include? विधि ओ (एन) जटिलता के साथ एक रैखिक खोज चलाएगी जो सरणी के आकार के आधार पर सुंदर बदसूरत हो सकती है।

यदि आप एक बड़ी (सॉर्टेड) ​​सरणी के साथ काम कर रहे हैं, तो मैं एक द्विआधारी खोज एल्गोरिथम लिखने पर विचार करूँगा जो बहुत मुश्किल नहीं होना चाहिए और ओ (लॉग एन) का सबसे खराब मामला है।

या यदि आप रूबी 2.0 का उपयोग कर रहे हैं, तो आप bsearch लाभ ले सकते हैं

मजेदार तथ्य,

आप एक case भावों में सरणी सदस्यता को जांचने के लिए * का उपयोग कर सकते हैं।

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

जब क्लॉज में थोड़ा * नोटिस करता है, तो यह सरणी में सदस्यता के लिए जांच करता है।

Splat ऑपरेटर के सभी सामान्य जादू व्यवहार लागू होता है, इसलिए उदाहरण के लिए यदि array वास्तव में एक सरणी नहीं है, लेकिन एक तत्व यह तत्व से मेल खाएगा।

यदि आपके मन में अधिक मान है … आप कोशिश कर सकते हैं:

उदाहरण: यदि बिल्ली और कुत्ते को सरणी में मौजूद है:

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

के बजाय:

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

नोट: सदस्य? और शामिल हैं? समान हैं।

यह एक पंक्ति में काम कर सकता है!

दूसरी तरफ भी है, भी!

मान लीजिए कि सरणी [: संपादित करें,: अपडेट, बनाएं,: शो] – अच्छी तरह से शायद पूरी सात घातक / शांत पापों 🙂

और कुछ स्ट्रिंग से वैध कार्रवाई खींचने के विचार के साथ और खिलौना – कहते हैं

मेरा भाई मुझे अपना प्रोफ़ाइल अपडेट करने के लिए चाहेंगे

उपाय

 [ :edit, :update, :create, :show ].select{|v| v if "my brother would like me to update his profile".downcase =~ /[,|.| |]#{v.to_s}[,|.| |]/} 

यदि हम उपयोग नहीं करना चाहते हैं include? यह भी काम करता है:

 ['cat','dog','horse'].select{ |x| x == 'dog' }.any? 

कैसे इस तरह के बारे में?

 ['Cat', 'Dog', 'Bird'].index('Dog') 
 ['Cat', 'Dog', 'Bird'].detect { |x| x == 'Dog'} => "Dog" !['Cat', 'Dog', 'Bird'].detect { |x| x == 'Dog'}.nil? => true 

यदि आप उपयोग नहीं करना चाहते हैं शामिल हैं? आप पहली बार एक सरणी में तत्व लपेट कर सकते हैं और फिर जांच लें कि क्या लिपटे हुए तत्व सरणी के प्रतिच्छेदन और लपेटा हुआ तत्व के बराबर है या नहीं। यह समानता के आधार पर एक बूलियन मान वापस करेगा I

 def in_array?(array, item) item = [item] unless item.is_a?(Array) item == array & item end 

ऐसा करने का एक और तरीका है:

 arr = ['Cat', 'Dog', 'Bird'] e = 'Dog' present = arr.size != (arr - [e]).size 
 array = [ 'Cat', 'Dog', 'Bird' ] array.include?("Dog") 

hash लिए arr को कनवर्ट करें, अब किसी भी कुंजी के लिए हे (1) गुणक के समय में hash = arr.map {|x| [x,true]}.to_h : hash = arr.map {|x| [x,true]}.to_h hash = arr.map {|x| [x,true]}.to_h

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

हैश के प्रदर्शन # has_key है? बनाम अर्रे # शामिल हैं?

 पैरामीटर हाश # है_के?  सरणी # शामिल 

 समय जटिलता ओ (1) ऑपरेशन ओ (एन) आपरेशन 

 प्रवेश प्रकार हाश [कुंजी] एक्सेस करता है यदि यह प्रत्येक तत्व के द्वारा बदलता है
                         तब तक सरणी के किसी भी मूल्य को वापस देता है
                         अरे में मान पाई जाती है
                         हैश # has_key?  कॉल
                         कॉल