【问题标题】:Ruby - iterate over array of irregularly repeating hashesRuby - 迭代不规则重复的哈希数组
【发布时间】:2018-08-29 23:47:26
【问题描述】:

哈希输入数组示例(带有一些规则和不规则的重复模式):

[{ key1 => value1 }, { key2 => value2 }, { key3 => value3 }, 
 { key4 => value4 }, { key3 => value5 }, { key4 => value6 }, 
 { key1 => value7 }, { key2 => value8 }, { key3 => value9 }, 
 { key4 => value10 }, { key3 => value11 }, { key4 =>  value12 }, { key3  => value13 }, { key4 => value14 },
 { key1 => value15 }, { key2 => value16 }, { key3 =>   value17 }, { key4 => value18 } ]

要求是将以上内容转换为:

 [ [{ key1 => value1 }, { key2 => value2 },
    { key3key4 => value3value4value5value6 } ]
   [ { key1 => value7 }, { key2 => value8 }, 
     { key3key4 =>       value9value10value11value12value13value14 }]
   [ { key1 => value15 }, { key2 => value16 }, { key3key4 =>   value17value18 }] ]

(注意,例如 key3key4 和 value5value6value7value8 等,只是键和值的串联)

输入结构可以是任意数量的重复哈希,其中 key3 和 key4 不规则出现,有时只有两个哈希,有时是 3,等等。

我了解 array.each 和 array.map 等,我认为要实现上述目标可能需要使用计数器或类似的工具,但到目前为止,我的努力很快就陷入了混乱,因此在这里发布一些关于如何最好地解决这个问题。

编辑:再解释一点,key3 和 key4(以及它们的值)被连接起来,因为它们是模式的每个循环中哈希重复(不规则)的键,并且希望将其折叠成一个键:value 输出中模式的每个“重复”中的值对散​​列。这些值是实际问题中的字符串,将它们连接起来是有意义的

【问题讨论】:

  • 您能否编辑您的帖子并添加更多理由。例如,当 key1 和 key2 没有连接时,为什么 key3 和 key4 连接起来?
  • 谢谢,我在最后添加了一些额外的文字

标签: arrays ruby hash iteration


【解决方案1】:

如果哈希在所有key3key4 之后重复,那么key1 将始终是第一个键,因此我们可以使用它和数组上的slice_before 方法将数组拆分为适当的分组:

output = input.slice_before { |hash| hash.has_key?('key1') }

如果分组条件不像“总是以key1 开头”那么简单,您可以使用slice_when 在出现两个相邻哈希值时拆分组,其中第一个哈希值包含可连接的键,而第二个没有:

output = input.slice_when do |current_hash, next_hash|
  concatenate_keys.any? { |key| current_hash.has_key?(key) } &&
    concatenate_keys.none? { |key| next_hash.has_key?(key) }
end 

从那里,我们只需要遍历并将所有 key3key4 哈希合并为一个哈希,我们可以使用 mapselectreject 来完成:

concatenate_keys = %w[key3 key4]
contains_concatenate_key = -> hash { concatenate_keys.any? { |key| hash.has_key?(key) } }

output = output.map do |grouping|
  concatenatable_hashes = grouping.select &contains_concatenate_key

  grouping.reject(&contains_concatenate_key) + [
    { concatenate_keys.join => concatenatable_hashes.flat_map(&:values).join }
  ]
end

p output
# => [[{"key1"=>"value1"}, {"key2"=>"value2"}, {"key3key4"=>"value3value4value5value6"}],
#     [{"key1"=>"value7"}, {"key2"=>"value8"}, {"key3key4"=>"value9value10value11value12value13value14"}],
#     [{"key1"=>"value15"}, {"key2"=>"value16"}, {"key3key4"=>"value17value18"}]]

【讨论】:

  • 啊 slice_when 和 slice_before,谢谢。是的,key1 总是在序列的开头,然后是 key2,然后是 key3 和 key4,其中 key3 和 key4 可以在任何单个 key1 起始序列中重复任意次数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-30
  • 2021-02-08
  • 2012-12-27
  • 1970-01-01
  • 2014-12-15
  • 2016-02-19
  • 1970-01-01
相关资源
最近更新 更多