0

I have a 2 dimensional array

v = [ ["ab","12"], ["ab","31"], ["gh","54"] ]

The first element of the subarray of v will have repeating elements, such as "ab". I want to create a hash that puts the key as the first element of the subarray, and values as an array of corresponding second elements from v.

please advice.

Further, I want this, h={"ab"=>["12","31"],"gh"=>["54"]} and then I want to return h.values, such that the array [["12","31"],["54"]] is returned

4

3 回答 3

4
v.inject(Hash.new{|h,k|h[k]=[]}) { |h, (k, v)| h[k] << v ; h}

What it does:

  • inject (also called reduce) is a fold. Wikipedia defines folds like this: "a family of higher-order functions that analyze a recursive data structure and recombine through use of a given combining operation the results of recursively processing its constituent parts, building up a return value".

  • The block form of Hash.new takes two arguments, the hash itself and the key. If your default argument is a mutable object, you have to set the default this way, otherwise all keys will point to the same array instance.

  • In inject's block, we get two arguments, the hash and the current value of the iteration. Since this is a two element array, (k, v) is used to destructure the latter into two variables.

  • Finally we add each value to the array for its key and return the entire hash for the next iteration.

于 2012-07-30T07:12:02.987 回答
1
v = [ ["ab","12"], ["ab","31"], ["gh","54"] ]

这将为您提供一个哈希,其中键是子数组中唯一的第一个元素。

h = v.inject({}) { |c,i| (c[i.first] ||= []) << i.last; c }

这会将散列转换回数组,以防万一您需要数组格式的数组。

arr = h.collect { |k,v| [k,v] }
于 2012-07-30T05:41:01.617 回答
1
v.inject({­}) do |res,­ ar|
  res[ar.fir­st] ||= []
  res[ar.fir­st] << ar.la­st
  res
end
于 2012-07-30T05:39:23.700 回答