我正在尝试使用一些匹配将数组转换为哈希。在将数组转换为哈希之前,我想合并像这样的值
"Desc,X1XXSC,C,CCCC4524,xxxs,xswd"
并从中创建哈希。规则是,数组的第一个值是Hash中的键,在数组中有重复键,对于那些我需要合并值并将其放在一个键下的键。 “描述:”是关键。我的程序看起来像这样。
p 'test sample application'
str = "Desc:X1:C:CCCC:Desc:XXSC:xxxs:xswd:C:4524"
arr = Array.new
arr = str.split(":")
p arr
test_hash = Hash[*arr]
p test_hash
我找不到解决问题的方法。如果有人可以指导我,那将会很感激。
答案 0 :(得分:3)
使用Facets的功能方法:
require 'facets'
str.split(":").each_slice(2).map_by { |k, v| [k, v] }.mash { |k, vs| [k, vs.join] }
#=> {"Desc"=>"X1XXSC", "C"=>"CCCC4524", "xxxs"=>"xswd"}
不是没有Facets就不能做到这一点,但由于核心缺少一些基本的抽象,它不会更长:
Hash[str.split(":").each_slice(2).group_by(&:first).map { |k, gs| [k, gs.map(&:last).join] }]
#=> {"Desc"=>"X1XXSC", "C"=>"CCCC4524", "xxxs"=>"xswd"}
答案 1 :(得分:2)
我相信你在这里寻找each_slice
和each_with_object
str = "Desc:X1:C:CCCC:Desc:XXSC:xxxs:xswd:C:4524"
hash = str.split(':').each_slice(2).each_with_object({}) do |(key, value), memo|
memo[key] ||= ''
memo[key] += value
end
hash # => {"Desc"=>"X1XXSC", "C"=>"CCCC4524", "xxxs"=>"xswd"}
答案 2 :(得分:2)
@Sergio Tulentsev解决方案的一个小变化:
str = "Desc:X1:C:CCCC:Desc:XXSC:xxxs:xswd:C:4524"
str.split(':').each_slice(2).each_with_object(Hash.new{""}){|(k,v),h| h[k] += v}
# => {"Desc"=>"X1XXSC", "C"=>"CCCC4524", "xxxs"=>"xswd"}
str.split(':')
会产生一个数组;无需使用arr = Array.new
each_slice(2)
将此数组的元素两个一个地提供给一个块或后面的方法,就像在这种情况下一样。
each_with_object
获取这两个元素(作为数组)并将它们与一个对象一起传递给一个块,该对象由:
(Hash.new{""})
此对象是一个具有特殊行为的空哈希:当一个键未找到时,它将以“”响应(而不是通常的nil) )。
{|(k,v),h| h[k] += v}
这是完成所有工作的代码块。它使用具有两个元素的数组并将其解构为两个字符串,分配给k和v;特殊哈希分配给h。 h [k]询问散列“Desc”的值的散列。它以“”响应,其中添加了“X1”。重复此过程,直到处理完所有元素。
答案 3 :(得分:1)
Enumerable#slice_before
是一个很好的方式。
str = "Desc:X1:C:CCCC:Desc:XXSC:xxxs:xswd:C:4524"
a = ["Desc","C","xxxs"] # collect the keys in a separate collection.
str.split(":").slice_before(""){|i| a.include? i}
# => [["Desc", "X1"], ["C", "CCCC"], ["Desc", "XXSC"], ["xxxs", "xswd"], ["C", "4524"]]
hsh = str.split(":").slice_before(""){|i| a.include? i}.each_with_object(Hash.new("")) do |i,h|
h[i[0]] += i[1]
end
hsh
# => {"Desc"=>"X1XXSC", "C"=>"CCCC4524", "xxxs"=>"xswd"}