सरणी में किसी अन्य सरणी से कोई मान शामिल है?


155

यदि किसी सरणी में दूसरे सरणी से कोई तत्व है, तो परीक्षण करने का सबसे कारगर तरीका क्या है?

नीचे दिए गए दो उदाहरण, प्रश्न का उत्तर देने के प्रयास foodsमें कोई तत्व शामिल है cheeses:

cheeses = %w(chedder stilton brie mozzarella feta haloumi reblochon)
foods = %w(pizza feta foods bread biscuits yoghurt bacon)

puts cheeses.collect{|c| foods.include?(c)}.include?(true)

puts (cheeses - foods).size < cheeses.size

जवाबों:


268
(cheeses & foods).empty?

जैसा कि मार्क-एंड्रे लैफ्यून ने टिप्पणियों में कहा, &रैखिक समय में काम करता है जबकि any?+ include?द्विघात होगा। डेटा के बड़े सेटों के लिए, रैखिक समय तेज होगा। छोटे डेटा सेटों के लिए, ली जार्विस के उत्तर द्वारा any?+ include?तेजी से दिखाया जा सकता है - शायद इसलिए कि &एक नया ऐरे आवंटित करता है जबकि दूसरा समाधान नहीं करता है और बूलियन को वापस करने के लिए एक साधारण नेस्टेड लूप के रूप में काम करता है।


3
जब जाँच की जाती है कि एक सरणी में दूसरे सरणी से एक तत्व शामिल है, तो क्या ऐसा करने के लिए अधिक समझ में नहीं आएगा (चीज और खाद्य पदार्थ) .any? के रूप में यह सही मूल्य देता है अगर सरणियों वास्तव में एक ही तत्व के होते हैं?
रयान फ्रांसिस

1
@RyanFrancis, डॉक्स: any?: विधि TRUE देता ब्लॉक कभी झूठी या नहीं के बराबर के अलावा किसी अन्य मान देता है। empty?: यदि स्व में कोई तत्व नहीं है, तो सच है।
नकीलोन

3
@ नाकिलोन मैं भी उलझन में हूं कि उत्तर (cheeses & foods).any?ओपी का सवाल क्यों नहीं है: अगर कोई खाद्य पदार्थ चीज में है? उनके उदाहरण में, "फेटा" दोनों में है, इसलिए परिणाम सही, सही होना चाहिए? तो .empty?चौराहे पर जांच क्यों ?
SuckerForMayhem 21

@SuckerForMayhem, क्योंकि ओपी का प्रश्न है "यदि कोई हो तो ... ?", न कि केवल "यदि कोई हो तो"। यदि " हैं ... " को छोड़ दिया जाता है, तो यह माना जाता है कि "यदि कोई सत्य है? " और इस तरह से सरणी के लिए गलत वापस आ जाएगा [false, false, false], जबकि यह स्पष्ट रूप से खाली नहीं है।
Nakilon

क्या एक्टिवरकॉर्ड स्तर में कोई कार्यान्वयन है?
ली चुन

35

कैसे Enumerable # किसी के बारे में ?

>> cheeses = %w(chedder stilton brie mozzarella feta haloumi)
=> ["chedder", "stilton", "brie", "mozzarella", "feta", "haloumi"]
>> foods = %w(pizza feta foods bread biscuits yoghurt bacon)
=> ["pizza", "feta", "foods", "bread", "biscuits", "yoghurt", "bacon"]
>> foods.any? {|food| cheeses.include?(food) }
=> true

बेंचमार्क स्क्रिप्ट:

require "benchmark"
N = 1_000_000
puts "ruby version: #{RUBY_VERSION}"

CHEESES = %w(chedder stilton brie mozzarella feta haloumi).freeze
FOODS = %w(pizza feta foods bread biscuits yoghurt bacon).freeze

Benchmark.bm(15) do |b|
  b.report("&, empty?") { N.times { (FOODS & CHEESES).empty? } }
  b.report("any?, include?") { N.times { FOODS.any? {|food| CHEESES.include?(food) } } }
end

परिणाम:

ruby version: 2.1.9
                      user     system      total        real
&, empty?         1.170000   0.000000   1.170000 (  1.172507)
any?, include?    0.660000   0.000000   0.660000 (  0.666015)

cheesesसेट में बदलकर आप इसमें सुधार कर सकते हैं ।
एकुचन

1
माणिक 2.2.7 और 2.3.4 पर मेरा अपना बेंचमार्क any?, include?था और सबसे तेज़ था, सबसे धीमा सेट करता था: gist.github.com/jaredmoody/d2a1e83de2f91fd6865920b01a8b497
Jared

4
यह मानदंड उल्लिखित विशिष्ट उदाहरण द्वारा पक्षपाती है और जरूरी नहीं कि एक अधिक सामान्य मामले में हो। यदि दो सरणियों के बीच कोई सामान्य तत्व नहीं थे, तो क्या होगा? यदि प्रत्येक पास पर एक अलग क्रम में सरणियाँ होती हैं तो क्या होगा? क्या होगा यदि दोनों सरणियों के अंत में फेटा दिखाई दिया? जैसा कि मार्क-एंड्रे ने कहा, सेट चौराहे रैखिक समय में निष्पादित होते हैं, इसलिए यह समझ में आता है कि यह सामान्य मामले के लिए बहुत अधिक स्केलेबल है, बजाय प्रश्न को स्पष्ट करने के लिए विशुद्ध रूप से इस्तेमाल किए गए एक विशिष्ट उदाहरण के बजाय।
user2259664

22

आप जांच कर सकते हैं कि चौराहा खाली है या नहीं।

cheeses = %w(chedder stilton brie mozzarella feta haloumi)
foods = %w(pizza feta foods bread biscuits yoghurt bacon)
foods & cheeses
=> ["feta"] 
(foods & cheeses).empty?
=> false

1
Set.new(cheeses).disjoint? Set.new(foods)

इसके अलावा मेरे (अवैज्ञानिक) बेंचमार्क में, सेट डिस्जाइंट
Jared

1
आपकी टिप्पणियों के लिए आभार। मुझे यकीन नहीं है कि यह सेट क्यों नहीं था। लेकिन मैंने इसे संपादित किया। मैंने 2.4.1 में आपके प्रदर्शन बेंचमार्क की कोशिश की। मेरा बेहतर था, लेकिन फिर भी सबसे अधिक शब्दों वाले असंबद्ध सेटों का उपयोग करना सबसे अच्छा नहीं था। मैंने अपना संस्करण आपकी टिप्पणी पर टिप्पणी में डाल दिया। मुझे भी लगता disjoint?है कि बहुत सुंदर है, विशेष रूप से "किसी भी ?, शामिल हैं?" की तुलना में। मूल प्रश्न ने सुरुचिपूर्ण और कुशल दोनों के बारे में पूछा।
दाविदकोवस्की

.to_setयहाँ विधि उपयोगी हो सकती हैcheeses.to_set.disjoint?(foods.to_set)
22

0
require "benchmark"
N = 1_000_000
puts "ruby version: #{RUBY_VERSION}"

CHEESES = %w(chedder stilton brie mozzarella feta haloumi).freeze
FOODS = %w(pizza feta foods bread biscuits yoghurt bacon).freeze

Benchmark.bm(15) do |b|
  b.report("&, empty?") { N.times { (FOODS & CHEESES).empty? } }  
  b.report("any?, include?") { N.times { FOODS.any? {|food| CHEESES.include?(food) } } }  
  b.report("disjoint?") { N.times { FOODS.to_set.disjoint? CHEESES.to_set }}
end  
                      user     system      total        real
&, empty?         0.751068   0.000571   0.751639 (  0.752745)
any?, include?    0.408251   0.000133   0.408384 (  0.408438)
disjoint?        11.616006   0.014806  11.630812 ( 11.637300)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.