我有以下数组:
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
但是想知道是否有更优雅,更干净或更鲁莽的方式?
答案 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对这种应用程序更有效。