2012-06-08 15 views
5

मैं एक साधारण सरणीकुत्तों की एक सरणी को एक हैश में tuples की रूबी सरणी कनवर्ट करें?

array = ["apple", "orange", "lemon"] 

array2 = [["apple", "good taste", "red"], ["orange", "bad taste", "orange"], ["lemon" , "no taste", "yellow"]] 

मैं कैसे इस हैश जब भी सरणी में तत्व array2 में प्रत्येक तत्व के पहले तत्व मिलान करने के लिए परिवर्तित कर सकते हैं है?

hash = {"apple" => ["apple" ,"good taste", "red"], 
     "orange" => ["orange", "bad taste", "orange"], 
     "lemon" => ["lemon" , "no taste", "yellow"] } 

मैं रूबी के लिए काफी नया हूं, और इस हेरफेर करने के लिए बहुत कुछ खर्च करता हूं, लेकिन कोई भाग्य नहीं, कोई मदद?

+0

क्या आप वास्तव में "array2 में प्रत्येक तत्व के पहले तत्व से मेल" से क्या मतलब है? – Mischa

+4

मेरा उत्तर संपादित न करें, एक टिप्पणी छोड़ें – Mischa

उत्तर

10

कुंजी और जोड़े के बीच मानचित्रण के आदेश array2 में पहले तत्व पर आधारित होना चाहिए, तो आप array बिल्कुल जरूरत नहीं है:

array2 = [ 
    ["apple", "good taste", "red"], 
    ["lemon" , "no taste", "yellow"], 
    ["orange", "bad taste", "orange"] 
] 

map = Hash[ array2.map{ |a| [a.first,a] } ] 
p map 
#=> { 
#=> "apple"=>["apple", "good taste", "red"], 
#=> "lemon"=>["lemon", "no taste", "yellow"], 
#=> "orange"=>["orange", "bad taste", "orange"] 
#=> } 

आप उपयोग करना चाहते हैं array तत्वों का एक उपसमूह चुनने के लिए है, तो आप ऐसा कर सकते हैं: कोड

# Use the map created above to find values efficiently 
array = %w[orange lemon] 
hash = Hash[ array.map{ |val| [val,map[val]] if map.key?(val) }.compact ] 
p hash 
#=> { 
#=> "orange"=>["orange", "bad taste", "orange"], 
#=> "lemon"=>["lemon", "no taste", "yellow"] 
#=> } 

if map.key?(val) और compact यह सुनिश्चित करता है कि array उन कुंजियों के लिए पूछता है जो array2 में मौजूद नहीं हैं, और O(n) समय में ऐसा कोई समस्या नहीं है।

+0

यह निम्न आवश्यकता को ध्यान में नहीं रखता है: "जब भी सरणी में तत्व सरणी में प्रत्येक तत्व के पहले तत्व से मेल खाता है"। – Mischa

+0

@ मिस्चा अब यह करता है। :) – Phrogz

2

यह आपको वांछित परिणाम प्राप्त करता है।

hash = {} 

array.each do |element| 
    i = array2.index{ |x| x[0] == element } 
    hash[element] = array2[i] unless i.nil? 
end 
+0

हाय, thx, क्या सरणी 2 क्रम में नहीं है? –

+1

वैसे यह आपके प्रश्न से स्पष्ट नहीं है। अगली बार जब आप अपने उदाहरण में अधिक स्पष्ट रूप से चाहते हैं तो उसे प्रतिबिंबित करें। 'सेब',' नारंगी 'और' नींबू ''array2' में एक से अधिक बार हो सकते हैं, यदि ऐसा है तो आप परिणामस्वरूप हैश को कैसे देखना चाहते हैं। कृपया एक स्पष्ट उदाहरण और अपेक्षित आउटपुट के साथ अपना प्रश्न अपडेट करें। – Mischa

+0

@ किटहो, यह काम करता है अगर सरणी क्रम में नहीं है। – Mischa

-1

ohh..I पर निम्नलिखित rassoc बाहर ओवरराइड करने के लिए

चेक परीक्षा आईआरबी

class Array 
    def rassoc obj, place=1 
    if place 
     place = place.to_i rescue -1 
     return if place < 0 
    end 

    self.each do |item| 
     next unless item.respond_to? :include? 

     if place 
     return item if item[place]==obj 
     else 
     return item if item.include? obj 
     end 
    end 

    nil 
    end 
end 

array = ["apple", "orange", "lemon"] 
array2 = [["apple", "good taste", "red"], ["orange", "bad taste", "orange"], ["lemon" , "no taste", "yellow"]] 

Hash[ array.map{ |fruit| [fruit, array2.rassoc(fruit, nil)]}] 
# this is what you want 

# order changed 
array2 = [["good taste", "red", "apple"], ["no taste", "lemon", "yellow"], ["orange", "bad taste", "orange"]] 

Hash[ array.map{ |fruit| [fruit, array2.rassoc(fruit, nil)]}] 
# same what you want after order is changed 
संबंधित मुद्दे