2012-06-08 66 views
5

Tôi có một mảng đơn giảnChuyển đổi mảng Ruby của bộ thành một băm cho một mảng các khóa?

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

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

làm thế nào tôi có thể chuyển đổi để băm này bất cứ khi nào phần tử trong mảng phù hợp với các yếu tố đầu tiên của mỗi phần tử trong array2?

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

Tôi khá mới mẻ với ruby ​​và dành nhiều thời gian để thực hiện thao tác này, nhưng không may mắn, có trợ giúp nào không?

+0

gì bạn biết chính xác ý nghĩa của "phù hợp với các yếu tố đầu tiên của mỗi phần tử trong array2"? – Mischa

+4

Không sửa câu trả lời của tôi, để lại một bình luận – Mischa

Trả lời

10

Nếu thứ tự của các ánh xạ giữa chìa khóa và cặp phải dựa trên các yếu tố đầu tiên trong array2, sau đó bạn không cần phải array tại tất cả:

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"] 
#=> } 

Nếu bạn muốn sử dụng array để chọn một tập hợp con của các nguyên tố, sau đó bạn có thể làm điều này:

# 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 đảm bảo rằng không có vấn đề gì nếu array yêu cầu các khóa không có trong array2 và thực hiện như vậy trong thời gian O(n).

+0

Điều này không tính đến yêu cầu sau: "bất cứ khi nào phần tử trong mảng khớp với phần tử đầu tiên của mỗi phần tử trong mảng2". – Mischa

+0

@Mischa Nó hiện nay. :) – Phrogz

2

Điều này giúp bạn đạt được kết quả mong muốn.

hash = {} 

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

Hi, thx, nếu array2 không theo thứ tự thì sao? –

+1

Điều đó không rõ ràng từ câu hỏi của bạn. Lần sau phản ánh những gì bạn muốn trong ví dụ của bạn rõ ràng hơn. Có thể 'apple',' orange' và 'lemon' xuất hiện nhiều hơn một lần trong' mảng2', nếu vậy bạn muốn băm tìm kiếm như thế nào. Vui lòng cập nhật câu hỏi của bạn với ví dụ rõ ràng và kết quả mong đợi. – Mischa

+0

@KitHo, hoạt động này nếu mảng không theo thứ tự. – Mischa

-1

ohh..I cám dỗ để ghi đè rassoc

Check-out sau đây trên IRB

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 
Các vấn đề liên quan