Ruby 压缩哈希的所有数组值

Ruby 压缩哈希的所有数组值,ruby,Ruby,我想压缩散列的所有数组值。我知道有一种方法可以将数组压缩在一起。我想用下面散列的值来做这件事 current_hash = {:a=>["k", "r", "u"], :b=>["e", " ", "l"], :c=>["d", "o", "w"], :d=>["e", "h"] } desired_outcome = "keder ohul

我想压缩散列的所有数组值。我知道有一种方法可以将数组压缩在一起。我想用下面散列的值来做这件事

current_hash = {:a=>["k", "r", "u"],
                :b=>["e", " ", "l"],
                :c=>["d", "o", "w"],
                :d=>["e", "h"]
                }

 desired_outcome = "keder ohulw"
我已经在上面列出了我想要的结果

current_hash.values.then { |first, *rest| first.zip(*rest) }.flatten.compact.join
Ruby
zip
的一个不幸之处是,第一个可枚举项必须是接收者,其他的必须是参数。在这里,我使用
然后
、参数解构和splat将第一个可枚举项与其余项分开
flatten
去掉列数组,
compact
去掉
nil
(虽然这并不是必需的,因为
join
会忽略它),而
join
会将数组变成字符串


注意Ruby
zip
将在接收器的长度处停止;因此,如果
:a
比其他的短,您可能会得到一个令人惊讶的结果。如果这是一个问题,请更新一个反映该场景的示例,以及期望的结果

Ruby
zip
的一个不幸之处是,第一个可枚举项必须是接收者,其他的必须是参数。在这里,我使用
然后
、参数解构和splat将第一个可枚举项与其余项分开
flatten
去掉列数组,
compact
去掉
nil
(虽然这并不是必需的,因为
join
会忽略它),而
join
会将数组变成字符串



注意Ruby
zip
将在接收器的长度处停止;因此,如果
:a
比其他的短,您可能会得到一个令人惊讶的结果。如果这是一个问题,请用一个反映该场景和预期结果的示例进行更新。

在这里,我充实了@Amadan在回答中水平线下方的评论。假设:

current_hash = { a:["k","r"], b:["e"," ","l"], c:["d","o","w"], d:["e", "h"] }
您希望返回“keder ohlw”
。如果您分别制作
[“k”,“r”]
[“e”,“l”,“d”,“o”,“w”],[“e”,“h”]
的接收器和参数,您将得到
“keder oh”
,其中省略了
的“l”
的“w”
。(参见,尤其是第3段。)

要包含这些字符串,您需要用
nil
s填充
[“k”,“r”]
,使其与最长值一样长,或者使
zip
的接收器具有相同长度的
nil
s数组。后一种方法可按如下方式实施:

vals = current_hash.values
  #=> [["k", "r"], ["e", " ", "l"], ["d", "o", "w"], ["e", "h"]] 
([nil]*vals.map(&:size).max).zip(*vals).flatten.compact.join
  #=> "keder ohlw" 
注:

您也可以使用而不是
zip

vals = current_hash.values
idx = (0..vals.map(&:size).max-1).to_a
  #=> [0, 1, 2] 
vals.map { |a| a.values_at(*idx) }.transpose.flatten.compact.join
  #=> "keder ohlw" 
看。注:


在这里,我充实了@Amadan在答案水平线下方的评论。假设:

current_hash = { a:["k","r"], b:["e"," ","l"], c:["d","o","w"], d:["e", "h"] }
您希望返回“keder ohlw”
。如果您分别制作
[“k”,“r”]
[“e”,“l”,“d”,“o”,“w”],[“e”,“h”]
的接收器和参数,您将得到
“keder oh”
,其中省略了
的“l”
的“w”
。(参见,尤其是第3段。)

要包含这些字符串,您需要用
nil
s填充
[“k”,“r”]
,使其与最长值一样长,或者使
zip
的接收器具有相同长度的
nil
s数组。后一种方法可按如下方式实施:

vals = current_hash.values
  #=> [["k", "r"], ["e", " ", "l"], ["d", "o", "w"], ["e", "h"]] 
([nil]*vals.map(&:size).max).zip(*vals).flatten.compact.join
  #=> "keder ohlw" 
注:

您也可以使用而不是
zip

vals = current_hash.values
idx = (0..vals.map(&:size).max-1).to_a
  #=> [0, 1, 2] 
vals.map { |a| a.values_at(*idx) }.transpose.flatten.compact.join
  #=> "keder ohlw" 
看。注:


current_hash.values.reduce(&:zip).join#⇒ “keder ohulw”
@AlekseiMatiushkin:很好。我想我犯了过早优化的错误…:佩赫
current_hash.values.reduce(&:zip).join#⇒ “keder ohulw”
@AlekseiMatiushkin:很好。我想我犯了过早优化的错误…:P