2015-11-02 151 views
0

我被朋友給了一個編碼挑戰,我一直在努力執行它。我應該採取一個數組,並操縱數據,並構建一個自定義哈希到他的規格。使用Ruby將「主列表」樣式嵌套數組轉換爲嵌套哈希

開始數據

[ 
     ['first_name', 'last_name', 'phone_number', 'level_of_caringness'], 
     ['Phteven', 'Cartwright', 911, 'None'], 
     ['Carol', 'Smellsbad', 666, 'Hateful'], 
     ['Bambam', 'Idontwanttomaketheseanymore', 134, 'QWERQWER'] 
    ] 

最終目標

{911: { first_name: "Phteven", last_name: 'Cartwright', phone_number: 911, level_of_caringness: 'None'}, 
666: {first_name: "Carol", last_name: 'Smellsbad', phone_number: 666, level_of_caringness: 'Hateful'} 
134: {first_name: "Bambam", last_name: 'Idontwanttomaketheseanymore', phone_number: 134, level_of_caringness: 'QWERQWER'} 

}

def array_to_hash3(array) 
keys = array.shift 
array.each_with_object({}) {|v, h| h[[array][2]] = {keys[0] => v[0], keys[1] => v[1], keys[2] => v[2], keys[3] => v[3]}} 

這讓我:

{nil=>{"first_name"=>"Bambam", "last_name"=>"Idontwanttomaketheseanymore", "phone_number"=>134, "level_of_caringness"=>"QWERQWER"}} 

所以我在園球,但也不能令人信服。

感謝您的輸入!

編輯

我能得到很多與此

def array_to_hash3(array) 
key = array.shift 
array.each_with_object({}) {|v, h| h[v[2]] = {key[0] => v[0], key[1] => v[1], key[2] => v[2], key[3] => v[3]}} 
end 

結果

​​

所以有一件事我留下的,是更接近原始請求想要將電話號碼用作符號而不是fixnum /整數鍵。那裏有任何想法?

編輯

終於得到它

def array_to_hash4(array) 
    key = array.shift 
    array.each_with_object({}) do |record, h| 
    h[record[2]] = Hash[key.zip(record)] 
    end 
end 

{ 
911=>{"first_name"=>"Phteven", 
     "last_name"=>"Cartwright", 
     "phone_number"=>911, 
     "level_of_caringness"=>"None"}, 
666=>{"first_name"=>"Carol", 
     "last_name"=>"Smellsbad", 
     "phone_number"=>666, 
     "level_of_caringness"=>"Hateful"}, 
134=>{"first_name"=>"Bambam",     
     "last_name"=>"Idontwanttomaketheseanymore", 
     "phone_number"=>134, 
     "level_of_caringness"=>"QWERQWER"} 
} 

回答

0
arr = [ 
    ['first_name', 'last_name', 'phone_number', 'level_of_caringness'], 
    ['Phteven', 'Cartwright', 911, 'None'], 
    ['Carol', 'Smellsbad', 666, 'Hateful'], 
    ['Bambam', 'Idontwanttomaketheseanymore', 134, 'QWERQWER'] 
] 

[arr.first].product(arr[1..-1]). 
    map { |keys, values| keys.zip(values).to_h }. 
    each_with_object({}) { |g,h| h.update(g["phone_number"]=>g) } 
    #=> [{911=>{"first_name"=>"Phteven", "last_name"=>"Cartwright", 
    #   "phone_number"=>911, "level_of_caringness"=>"None"}}, 
    # {666=>{"first_name"=>"Carol", "last_name"=>"Smellsbad", 
    #   "phone_number"=>666, "level_of_caringness"=>"Hateful"}}, 
    # {134=>{"first_name"=>"Bambam", "last_name"=>"Idontwanttomaketheseanymore", 
    #   "phone_number"=>134, "level_of_caringness"=>"QWERQWER"}}] 

Array#to_h來用Ruby 2.0版,因此,如果您使用的是早期版本,在該塊使用Hash[keys.zip(values)]

的步驟:

a = [arr.first].product(arr[1..-1]) 
    #=> [[["first_name", "last_name", "phone_number", "level_of_caringness"], 
    #  ["Phteven", "Cartwright", 911, "None"]], 
    # [["first_name", "last_name", "phone_number", "level_of_caringness"], 
    #  ["Carol", "Smellsbad", 666, "Hateful"]], 
    # [["first_name", "last_name", "phone_number", "level_of_caringness"], 
    #  ["Bambam", "Idontwanttomaketheseanymore", 134, "QWERQWER"]]] 

b = a.map { |keys, values| keys.zip(values).to_h } 
    #=> [{"first_name"=>"Phteven", "last_name"=>"Cartwright", 
    #  "phone_number"=>911, "level_of_caringness"=>"None"}, 
    # {"first_name"=>"Carol", "last_name"=>"Smellsbad", 
    #  "phone_number"=>666, "level_of_caringness"=>"Hateful"}, 
    # {"first_name"=>"Bambam", "last_name"=>"Idontwanttomaketheseanymore", 
    #  "phone_number"=>134, "level_of_caringness"=>"QWERQWER"}] 

傳遞給mapa第一值的塊計算如下:

keys, values = [["first_name", "last_name", "phone_number", "level_of_caringness"], 
       ["Phteven", "Cartwright", 911, "None"]] 
    #=> [["first_name", "last_name", "phone_number", "level_of_caringness"], 
    # ["Phteven", "Cartwright", 911, "None"]] 
keys 
    #=> ["first_name", "last_name", "phone_number", "level_of_caringness"] 
values 
    #=> ["Phteven", "Cartwright", 911, "None"] 
c = keys.zip(values) 
    #=> [["first_name", "Phteven"], ["last_name", "Cartwright"], 
    # ["phone_number", 911], ["level_of_caringness", "None"]] 
c.to_h 
    #=> {"first_name"=>"Phteven", "last_name"=>"Cartwright", 
    # "phone_number"=>911, "level_of_caringness"=>"None"} 

最後一步僅僅散列陣列轉換爲所示的散列更早:

b.each_with_object({}) { |g,h| h.update(g["phone_number"]=>g) } 
0

假設你hav E在可變master_list數據:

master_list[1..-1].each_with_object({}) do |arr, m| 
    m[arr[2]] = Hash[master_list[0].map(&:to_sym).zip(arr)] 
end 

=> {911=> 
    {:first_name=>"Phteven", 
     :last_name=>"Cartwright", 
     :phone_number=>911, 
     :level_of_caringness=>"None"}, 
    666=> 
    {:first_name=>"Carol", 
     :last_name=>"Smellsbad", 
     :phone_number=>666, 
     :level_of_caringness=>"Hateful"}, 
    134=> 
    {:first_name=>"Bambam", 
     :last_name=>"Idontwanttomaketheseanymore", 
     :phone_number=>134, 
     :level_of_caringness=>"QWERQWER"}} 
+0

@CarySwoveland謝謝。我根據你的意見改變了解決方案。 – davidrac

0
require 'pp' 

data = [ 
    ['first_name', 'last_name', 'phone_number', 'level_of_caringness'], 
    ['Phteven', 'Cartwright', 911, 'None'], 
    ['Carol', 'Smellsbad', 666, 'Hateful'], 
    ['Bambam', 'Idontwanttomaketheseanymore', 134, 'QWERQWER'] 
] 

result = {} 
cols = data[0] 

data[1..-1].each do |row| 
    inner_hash = {} 

    cols.each_with_index do |col, i| 
    inner_hash[col] = row[i] 
    end 

    result[row[2].to_s.to_sym] = inner_hash 
end 

pp result 

--output:-- 
{:"911"=> 
    {"first_name"=>"Phteven", 
    "last_name"=>"Cartwright", 
    "phone_number"=>911, 
    "level_of_caringness"=>"None"}, 
:"666"=> 
    {"first_name"=>"Carol", 
    "last_name"=>"Smellsbad", 
    "phone_number"=>666, 
    "level_of_caringness"=>"Hateful"}, 
:"134"=> 
    {"first_name"=>"Bambam", 
    "last_name"=>"Idontwanttomaketheseanymore", 
    "phone_number"=>134, 
    "level_of_caringness"=>"QWERQWER"}} 

使用外部迭代:

require 'pp' 

data = [ 
    ['first_name', 'last_name', 'phone_number', 'level_of_caringness'], 
    ['Phteven', 'Cartwright', 911, 'None'], 
    ['Carol', 'Smellsbad', 666, 'Hateful'], 
    ['Bambam', 'Idontwanttomaketheseanymore', 134, 'QWERQWER'] 
] 

result = {} 
keys = data[0].each 

data[1..-1].each do |row| 
    values = row.each 
    inner_hash = {} 

    loop do 
    inner_hash[keys.next] = values.next 
    end 

    result[row[2].to_s.to_sym] = inner_hash 
    keys.rewind 
end 

pp result 

--output:-- 
{:"911"=> 
    {"first_name"=>"Phteven", 
    "last_name"=>"Cartwright", 
    "phone_number"=>911, 
    "level_of_caringness"=>"None"}, 
:"666"=> 
    {"first_name"=>"Carol", 
    "last_name"=>"Smellsbad", 
    "phone_number"=>666, 
    "level_of_caringness"=>"Hateful"}, 
:"134"=> 
    {"first_name"=>"Bambam", 
    "last_name"=>"Idontwanttomaketheseanymore", 
    "phone_number"=>134, 
    "level_of_caringness"=>"QWERQWER"}} 
0

下面是一個容易閱讀和理解的解決方案。

def array_to_hash(list) 
    result = {} 
    keys = list.shift.map(&:to_sym) 
    list.each{ |ar| result[ar[2]] = Hash[keys.zip(ar)]} 
    result 
end