2017-01-03 22 views
0

我有散列的數組:紅寶石無法值映射到散列的數組,尋找替代

data1 = [{:first => 1, :second => 'whatever'},{:first => 2, :second => 'something'}] 

test_merge = {'whatever' => {:third => 1, :fourth => 1}, 'something' => {:third => 2, :fourth => 2}} 

我想這樣的輸出:

[{:first=>"MODIFIED", :second=>"whatever", :test_field=>"added", :third=>1, :fourth=>1, "sdsds"=>"sdsds", "2x4"=>8}, {:first=>"MODIFIED", :second=>"something", :test_field=>"added", :third=>2, :fourth=>2, "sdsds"=>"sdsds", "2x4"=>8}] 

我也映射和合並:

data2 = data1.map do |d| 
    d[:test_field] = 'added' 
    d[:first] = 'MODIFIED' 
    d2 = test_merge[d[:second]] 
    d = d.merge(d2) 
    d['sdsds'] = 'sdsds' 
    d['2x4'] = 2*4 
    end 

我:

data1 #=> [{:first=>"MODIFIED", :second=>"whatever", :test_field=>"added"}, {:first=>"MODIFIED", :second=>"something", :test_field=>"added"}] 
data2 #=> [8, 8] 

這可以,如果我做

data2 = data1.map do |d| 
     d[:test_field] = 'added' 
     d[:first] = 'MODIFIED' 
     d2 = {:test_field_two => 'notadded'} 
     d = d.merge(d2) 
     d['sdsds'] = 'sdsds' 
     d['2x4'] = 2*4 
     d #or d=d 
end 

是固定的,但爲什麼我需要插入到底(dd=dd?最後寫d看起來很難看。沒有其他方法可以做到這一點,我需要如上所述的準確輸出?

編輯:2017年1月3日(不要讀這個編輯,如果你正在閱讀的第一次的問題,一切都在上面提到的)

我有必要使用.map內合併,因爲我有得到了另一個哈希如下:

test_merge = {'whatever' => {:third => 1, :fourth => 1}, 'something' => {:third => 2, :fourth => 2}} 

這需要合併這樣的。每個裏面(合併不會。每個工作很遺憾,所以我不得不使用地圖)或.MAP

d = d.merge(test_merge[d[:second]]) 

'2x4',:first和其他鍵是重要的,需要設置/修改。

如果我需要修改d [:first],它應該被修改。

我試圖.each由史蒂夫提到,

data1 = [{:first => 1, :second => 'whatever'},{:first => 2, :second => 'something'}] 

    test_merge = {'whatever' => {:third => 1, :fourth => 1}, 'something' => {:third => 2, :fourth => 2}} 
     data1.each do |d| 
     d[:test_field] = 'added' 
     d[:first] = 'MODIFIED' 
     d2 = test_merge[d[:second]] 
     d = d.merge(d2) 
     d['sdsds'] = 'sdsds' 
     d['2x4'] = 2*4 
     end 

這是我得到的結果是:

[{:first=>"MODIFIED", :second=>"whatever", :test_field=>"added"}, {:first=>"MODIFIED", :second=>"something", :test_field=>"added"}] 

那不是我的預期輸出。這有什麼黑客嗎?

回答

4

使用塊執行map時,塊的最後執行行是新數組中返回的內容。

因此,如果最後一行是...

d['2x4'] = 2*4 

然後,它的2 * 4(8)這是返回。

設置塊的最後一行...

d 

...意味着返回d變量(整個散列)的值。

如果您只是想更改散列並且不需要返回數組,則不需要使用map。改爲使用each。 (編輯考慮到Eric關於淺層重複的觀察)。

data2 = data1.map{|d| d.dup} 
data2.each do |d| 
    d[:test_field] = 'added' 
    d[:test_field_two] = 'notadded' 
    d['sdsds'] = 'sdsds' 
    d['2x4'] = 2*4 
end 
+1

'是不是有另一種方法呢?':) –

+0

是的,不要使用'map'。改爲使用'each'。看到我修改後的答案。 – SteveTurczyn

+0

我認爲'map'的目的是避免使用'dup'和'each'。 –

2

Hash#merge返回合併哈希不改變原來的一個,這樣你就可以直接添加新|key,value|對並返回所需的哈希:

data2 = data1.map do |h1| 
    h1.merge(:test_field  => 'added', 
      :test_field_two => 'not_added', 
      'sdsds'   => 'sdsds', 
      '2x4'   => 2 * 4) 
end 

data2現在是:

[{:first=>1, 
    :second=>"whatever", 
    :test_field=>"added", 
    :test_field_two=>"not_added", 
    "sdsds"=>"sdsds", 
    "2x4"=>8}, 
{:first=>2, 
    :second=>"something", 
    :test_field=>"added", 
    :test_field_two=>"not_added", 
    "sdsds"=>"sdsds", 
    "2x4"=>8}] 

data1仍然是:

[{:first=>1, :second=>"whatever"}, {:first=>2, :second=>"something"}] 
0

我想這可能會更好!雖然我不確定我是否正確理解了這個問題。希望這可以幫助。

data1 = [{:first => 1, :second => 'whatever'},{:first => 2, :second => 'something'}] 

d2 = {:test_field_two => 'notadded', "sdsds"=>"sdsds", "2x4"=>2*4} 

data2 = data1.map do |d| d.merge(d2) end 

#=> [{:first=>1, :second=>"whatever", :test_field_two=>"notadded", "sdsds"=>"sdsds", "2x4"=>8}, {:first=>2, :second=>"something", :test_field_two=>"notadded", "sdsds"=>"sdsds", "2x4"=>8}] 
+1

我認爲你沒有正確理解它。在這個問題中,'data1'沒有改變,'data2'是新的散列數組。你修改'data1' –