在阅读csv文件后,我有了这个数据结构:
[["name1 | value1 | value2 | value3 | value4 "],
["name2 | value1 | value2 | value3 | value4 "],...]
我需要将其转换为Hash,如下所示:
{"name1" => "value1 | value2 | value3 | value4",
"name2" => "value1 | value2 | value3 | value4",...}
或者,更好的是:
{"name1" => ["value1","value2","value3","value4"],
"name2" => ["value1","value2","value3","value4"],...}
我发现了许多将数组数组转换为哈希值的方法,但是没有一种方法可以将内部数组中的第一个元素作为Hash的键使用。
有人能提出一个优雅的解决方案吗?
答案 0 :(得分:2)
rows = [["name1 | value1 | value2 | value3 | value4 "],
["name2 | value1 | value2 | value3 | value4 "],]
h = Hash[
rows.flatten.
map { |r| r = r.split('|').map(&:strip); [r.first, r.drop(1)] }
]
# => {"name1"=>["value1", "value2", "value3", "value4"],
# "name2"=>["value1", "value2", "value3", "value4"]}
我有点好奇你是如何到达那个输入结构的。如果您使用分隔符“|”读取CSV,则可能会更喜欢以下内容:
[["name1", "value1", "value2", "value3", "value4"],
["name2", "value1", "value2", "value3", "value4"]]
外部地图中的r = r.split('|').map(&:strip)
是关于转换的内容。
如果你有这种形式,转换为哈希要简单得多:
Hash[ rows.map { |r| [r.first, r.drop(1)] } ]
答案 1 :(得分:1)
除了@ dbenhur的回答。假设CSV类可以处理分隔符,并且您获得了如下基本结构:
rows = [["name1", "value1", "value2", "value3", "value4"],
["name2", "value1", "value2", "value3", "value4"]]
您可以使用splat运算符转换它:
Hash[rows.map { |name, *values| [name, values] }]
# => {"name1"=>["value1", "value2", "value3", "value4"], "name2"=>["value1", "value2", "value3", "value4"]}
答案 2 :(得分:0)
def to_hash(a)
h = {}
a.each do |item|
a2 = item.first.strip.split(' | ')
h[a2.shift] = a2
end
h
end
用法:
a = [["name1 | value1 | value2 | value3 | value4 "],
["name2 | value1 | value2 | value3 | value4 "]]
to_hash(a)
# => {"name1"=>["value1", "value2", "value3", "value4"],
# "name2"=>["value1", "value2", "value3", "value4"]}
答案 3 :(得分:0)
你可以试试这个:
csv.inject({}) do |memo, item|
parts = item.first.split('|').map(&:strip)
memo[parts.first] = parts.slice(1,parts.size)
memo
end
给你{"name1" => ["value1","value2","value3","value4"],
"name2" => ["value1","value2","value3","value4"],...}
另外,每当我编写像memo[parts.first] = parts.slice(1,parts.size)
这样的代码时,我真的希望Ruby添加head
和tail
方法。