如何将数组数组(从读取csv文件)转换为哈希

时间:2013-04-12 19:55:41

标签: ruby arrays csv hash

在阅读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的键使用。

有人能提出一个优雅的解决方案吗?

4 个答案:

答案 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添加headtail方法。