2015-08-24 3 views
6

मेरे पास दो सरणी हैं, एक डेटा के साथ और एक इंडेक्स के साथ। मैं जानना चाहता हूं कि में दी गई स्थिति पर data में तत्वों को हटाने के कुछ अच्छे तरीके हैं या नहीं। मैं सरल यात्रा कर सकता है, लेकिन मैं सोच रहा हूँ क्या सबसे छोटा रास्ता है:किसी अन्य सरणी में इंडेक्स पर मौजूद सरणी से तत्वों को कैसे हटाएं

data में
data = ['a','b','c','a','b','c','a','b','c'] 
indexes = [2,5,8] 

//some code here 

तत्वों चले गए हैं जब अनुक्रमित सरणी सूचकांकों में संख्या के साथ मेल खाना हुआ। यह इस तरह दिखना चाहिए:

['a','b','a','b','a','b'] 
+0

बस एक संयोग हम सभी 'सी' को यहां हटा रहे हैं? – Anthony

+0

हाँ प्रदर्शन प्रदर्शन –

+0

पोल: [Array # delete_at] (http://ruby-doc.org/core-2.2.0/Array.html#method-i-delete_at) को 'delete_at (i) 'से बदला जाना चाहिए 'delete_at (* i)'? –

उत्तर

5
data.values_at(*data.each_index.to_a - indexes) 
# => ["a", "b", "a", "b", "a", "b"] 
+2

कोई भी इससे बेहतर समाधान नहीं ढूंढ सकता है। बहुत बढ़िया जवाब। –

+2

यह वास्तव में सही है। – ndn

4

मैं नीचे के रूप में करना होगा:

data = ['a','b','c','a','b','c','a','b','c'] 
indexes = [2,5,8] 
data.values_at(*(0...data.size).to_a - indexes) 
# => ["a", "b", "a", "b", "a", "b"] 
+2

मुझसे एक बिंदु। – sawa

+2

@sawa मुझे अच्छा लगता है कि हमने वही तरीका सोचा ... :) लेकिन आप तेज़ थे। –

+0

यह वास्तव में एक अच्छा जवाब है, लेकिन यह ध्यान दिया जाना चाहिए कि दृश्यों के पीछे सरणी घटाव पुनरावृत्ति का उपयोग करता है। –

1
new_data = data.each_with_index.reject do |value,index| 
    indexes.include? index 
end.map(&:first) 

न्यू जवाब यह है कि वास्तव में इस समय काम करता है - यह (एन^2) हे में चलता है और मुझे इंडेक्स पर पुन: प्रयास किए बिना इसे करने का कोई तरीका नहीं दिख रहा है।

4

पुनरावृत्ति के बिना इसे करना एक अच्छा लक्ष्य जैसा प्रतीत हो सकता है, लेकिन सही किया गया पुनरावृत्ति सही तेज़ होने वाला है।

मानक महत्वपूर्ण हैं:

ttm(DATA)   # => ["a", "b", "a", "b", "a", "b"] 
devon_parsons(DATA) # => ["a", "b", "a", "b", "a", "b"] 
arup_rakshit(DATA) # => ["a", "b", "a", "b", "a", "b"] 
sawa(DATA)   # => ["a", "b", "a", "b", "a", "b"] 

भागो मानक:

n = 100_000 
Benchmark.bm(13) do |b| 
    b.report('ttm:')   { n.times { ttm(DATA)   } } 
    b.report('devon_parsons') { n.times { devon_parsons(DATA) } } 
    b.report('arup_rakshit') { n.times { arup_rakshit(DATA) } } 
    b.report('sawa')   { n.times { sawa(DATA)   } } 
end 

कौन सा में परिणाम:

require 'benchmark' 

DATA = ['a','b','c','a','b','c','a','b','c'] 
INDEXES = [2,5,8] 

def ttm(data) 
    d2 = data.dup 
    INDEXES.sort.reverse.each{ |i| d2.delete_at(i) } 
    d2 
end 

def devon_parsons(data) 
    new_data = data.each_with_index.reject do |value,index| 
    INDEXES.include? index 
    end.map(&:first) 
    new_data 
end 

def arup_rakshit(data) 
    data.values_at(*(0...data.size).to_a - INDEXES) 
end 

def sawa(data) 
    data.values_at(*data.each_index.to_a - INDEXES) 
end 

यकीन है कि यह सेब परीक्षण करने के लिए एक सेब है बनाओ

# >>      user  system  total  real 
# >> ttm:   0.130000 0.000000 0.130000 ( 0.127559) 
# >> devon_parsons 0.530000 0.000000 0.530000 ( 0.535929) 
# >> arup_rakshit 0.250000 0.000000 0.250000 ( 0.255295) 
# >> sawa   0.300000 0.010000 0.310000 ( 0.305376) 

डेटा का आकार बढ़ता है:

DATA2 = DATA * 100 
Benchmark.bm(13) do |b| 
    b.report('ttm:')   { n.times { ttm(DATA2)   } } 
    b.report('devon_parsons') { n.times { devon_parsons(DATA2) } } 
    b.report('arup_rakshit') { n.times { arup_rakshit(DATA2) } } 
    b.report('sawa')   { n.times { sawa(DATA2)   } } 
end 

परिणाम वास्तव में बदलने के लिए:

# >>      user  system  total  real 
# >> ttm:   0.320000 0.090000 0.410000 ( 0.420074) 
# >> devon_parsons 39.170000 0.080000 39.250000 (39.265062) 
# >> arup_rakshit 9.950000 0.010000 9.960000 ( 9.975699) 
# >> sawa   9.940000 0.020000 9.960000 ( 9.959036) 

यह परीक्षण करने के लिए क्या सरणी आकार में परिवर्तन के रूप में होता वास्तव में महत्वपूर्ण है। सरणी बढ़ने के साथ-साथ छोटी सी सरणी पर जो भी चल सकता है वह नाटकीय रूप से धीमा हो सकता है। और, अक्सर, कुछ करने के लिए एक अच्छा तरीका लगता है जो बहुत धीमा हो जाता है क्योंकि छिपी हुई लागतें होती हैं। बेंचमार्क इन चीजों को समझने में हमारी मदद करते हैं।

नोट: sort.reverse का उपयोग करना बहुत महत्वपूर्ण है। उन लोगों के बिना सरणी उलझ जाएगी।


तरह आगे sort_by लिए सुधार किया जा सकता (&: ही)

require 'benchmark' 

array = (0..99).to_a.shuffle 
n = 100_000 

Benchmark.bm(7) do |b| 
    b.report('sort:') { n.times { array.sort    } } 
    b.report('sort_by:') { n.times { array.sort_by(&:itself) } } 
end 

में परिणामी:

:

   user  system  total  real 
sort:  0.460000 0.010000 0.470000 ( 0.480236) 
sort_by: 3.600000 0.030000 3.630000 ( 3.627871) 

सरणी आकार बढ़ाने से

में परिणामी:

data = ['a','b','c','a','b','c','a','b','c'] 
indexes = [2,5,8] 

updated_data = data.dup 
indexes.each { |i| updated_data[i] = nil} 
updated_data.compact! 
p updated_data # Prints ["a", "b", "a", "b", "a", "b"] 

जहाँ तक बेंचमार्क के रूप में चला जाता है, टिन मनुष्य के कोड का उपयोग कर, यह सबसे अच्छा प्रदर्शन करने के लिए लगता है:

    user  system  total  real 
sort:   9.520000 0.120000 9.640000 ( 9.659246) 
sort_by:  53.530000 0.720000 54.250000 (54.321285) 
+0

प्रबुद्ध। धन्यवाद! –

+0

मेरे पास एक समाधान है, जो बेहतर प्रदर्शन करता प्रतीत होता है - क्या यह वाकई बेहतर या झुका हुआ है? –

+0

ने कहा कि मेरा एन^2 समय में था: पी –

0

यहाँ मेरी समाधान है। सुनिश्चित नहीं है कि indexes सरणी के छोटे आकार के साथ इसका कुछ संबंध है या नहीं।

    user  system  total  real 
ttm:   0.125000 0.000000 0.125000 ( 0.113075) 
devon_parsons 0.484000 0.000000 0.484000 ( 0.491327) 
arup_rakshit 0.219000 0.000000 0.219000 ( 0.221149) 
sawa   0.250000 0.000000 0.250000 ( 0.253168) 
wandmaker  0.094000 0.016000 0.110000 ( 0.095063) 

# Run 2 with larger data 
        user  system  total  real 
ttm:   0.422000 0.188000 0.610000 ( 0.596413) 
devon_parsons 39.328000 0.000000 39.328000 (39.489394) 
arup_rakshit 10.078000 0.562000 10.640000 (10.644099) 
sawa   10.219000 0.110000 10.329000 (10.328250) 
wandmaker  0.359000 0.062000 0.421000 ( 0.423282) 
+2

क्या होगा यदि ओपीएस सरणी में निल्स शामिल थे जो महत्वपूर्ण थे? आप 'इंडेक्स' द्वारा निर्दिष्ट डेटा को हटा नहीं पाएंगे। इसके खिलाफ सुरक्षा के लिए आपको कोड की आवश्यकता है। –

+0

@theTinMan हाँ, यह समझ में आता है। –

संबंधित मुद्दे

 संबंधित मुद्दे