2012-08-27 61 views
0

有單對散列的陣列,這樣的:紅寶石 - 獲取從散列數組鍵和值容易

arguments = [{:name=>"ABCD"},{:title=>"Awesome"},{:number=>4}] 

我通過需要循環和拉各一次性作爲鍵和值。現在,我這樣做:

def methodname(*arguments, &block) 
    arguments.each do |arg| 
    arg.each do |key, value| 
     # use my key and value 
    end 
    end 
    # use the &block here in awesome ways 
end 

Ick。有一個更好的方法,所以我問,如果有人知道這一點。我搜索了,似乎無法在StackOverflow上找到這個特定的問題,但讓我知道它是否在那裏。

編輯:添加上下文到代碼示例。

+0

那......對我來說實際上看起來並不好。您正在迭代一個數組,該數組需要一行,並且您正在迭代散列中的每個鍵 - 值對,這需要一行。這就像清潔和簡單。 – Matchu

+2

我懷疑他希望避免「迭代每個鍵值對」,因爲只有一個*鍵值對。 –

+0

@JörgWMittag:啊,很好的電話。疑難雜症。 – Matchu

回答

2

如果參數都應該是唯一的......

arguments.inject({},:merge).each { ... } 

FWIW - 如果你可以改變這種數據結構,這可能是一個好主意,這樣做。這個數據最好用一個散列表示。

你也可以用不同的方式定義你的方法,並完全避免這個問題。

irb(main):011:0> def foo(kwargs={},&block) 
irb(main):012:1> pp kwargs 
irb(main):013:1> end 
irb(main):025:0> foo(:biz=>1,:baz=>2) 
{:biz=>1, :baz=>2} 
=> nil 
+0

我同意改變數據結構。這是我得到這個: def methodname(*參數,&塊) #東西 結束 打擾的蠢事格式化......你明白了。 –

+1

順便說一句:你可以改寫'arguments.inject({},:merge)'。或者只是'arguments.inject(:merge)',如果你確定至少會有一個條件。 –

+0

@dfb我得到語法錯誤,意外的tPOW,期待')'。注意這是RubyMotion ...可能會使事情變得複雜一點。 –

1
arguments.each do |arg| 
    (key, value), = *arg 
    # use my key and value 
end 

我猜你是否認爲這是「更好的方式」主要取決於你的隊友是否明白分配在Ruby中是如何工作的。

+0

謝謝,這看起來很合理。查看其他最優雅解決方案的答案。 –

+0

順便說一句:後面的逗號很容易錯過,也許引入一個虛擬變量會更易讀:'(key,value),_ = * arg'。我對此很感興趣。 –

2

由於這不是一個常見的習慣用語,所以你不會找到一個真正乾淨的解決方案。無論如何,這裏是它一個像樣的射門:

arguments.map(&:first).each do |key, value| 
    # use key and value for something 
end 

該解決方案利用了以下事實:Hash優勢,作爲一個Enumerable,具有first方法返回的第一個結果是會產生迭代的,所以{:foo => :bar}.first == [:foo, :bar]。通過所有的哈希映射,你很好去。

+0

謝謝,這是一個很好的答案,但重新定義該方法最終成爲更好的解決方案。 –

+1

@JamonHolmgren:啊,看到上下文,是的,這絕對是更好的答案。很高興它全部排序:) – Matchu