在Ruby中的新数组中对多维数组中的值进行排序和存储

时间:2009-10-23 14:15:14

标签: ruby arrays

我有以下数组:

votes_array = [["2", "1"], ["2", "4"], ["4", "3"], ["3", "4"], ["1", "N"], ["3", "1"], ["1", "2"], ["4", "1"], ["0", "1"], ["0", "2"], ["1", "3"], ["1", "4"]]

我想创建一个新的数组(或散列),通过第一个选项存储votes_array项,以便新数组看起来像这样:

candidate_votes = [
                   {"id" => "0", "votes" => [["0", "1"],["0","2"]]}, 
                   {"id" => "1", "votes" => [["1", "N"],["1","2"],["1","3"],["1","4"]]},
                   etc,
                   etc]

“投票”键中的投票顺序并不重要,只是将所有投票分成相关的ID。

我使用以下代码:

first_preferences = votes_array.map(&:first)
valid_candidates = first_preferences.uniq
valid_candidates.each do |candidate|
   these_votes = votes_array.find_all { |i| i[0] == candidate }
   candidate_votes << {"id" => candidate, "votes" => these_votes}
end  

但是想知道是否有更优雅,更干净或更鲁莽的方式?

3 个答案:

答案 0 :(得分:4)

使用Ruby 1.8.7+,它是一个单行程序:

candidate_votes = votes_array.group_by {|pair| pair[0]}

漂亮的打印candidate_votes会返回

{"0"=>[["0", "1"], ["0", "2"]],
 "1"=>[["1", "N"], ["1", "2"], ["1", "3"], ["1", "4"]],
 "2"=>[["2", "1"], ["2", "4"]],
 "3"=>[["3", "4"], ["3", "1"]],
 "4"=>[["4", "3"], ["4", "1"]]}

答案 1 :(得分:1)

这是一个创建candidate_votes作为哈希的人。它可能会快一点,因为您只需要迭代votes_array一次:

candidate_votes = {}
votes_array.each do |id, vote|
  candidate_votes[id] ||= {"id" => id, "votes" => []}
  candidate_votes[id]["votes"] << [id, vote]
end

这将得到如下结果:

candidate_votes = {
                    "0" => {"votes" => [["0", "1"], ["0", "2"]], "id" => "0"},
                    ... etc ...
                  }

答案 2 :(得分:-1)

我认为您可以使用以下内容更简洁地组织输出:

# Use Enumerable#inject to convert Array to Hash
results = votes_array.inject({ }) do |hash, vote|
  # Create hash entry for candidate if not defined (||=)
  hash[vote[0]] ||= { :votes => [ ] }

  # Add vote to candidate's array of votes
  hash[vote[0]][:votes] << vote[1]

  # Keep hash for next round of inject
  hash
end

# => {"0"=>{:votes=>["1", "2"]}, "1"=>{:votes=>["N", "2", "3", "4"]}, "2"=>{:votes=>["1", "4"]}, "3"=>{:votes=>["4", "1"]}, "4"=>{:votes=>["3", "1"]}}

作为一个注释,在Ruby中使用Symbols for Hash键是有利的,因为它们通常比Strings对这种应用程序更有效。