【问题标题】:Sort and store values from multidimensional array in new array in Ruby将多维数组中的值排序并存储在 Ruby 中的新数组中
【发布时间】:2009-10-23 14:15:13
【问题描述】:

我有以下数组:

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]

'votes' 键中的投票顺序并不重要,只是所有的投票都被分成相关的 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  

但想知道是否有更优雅、更清洁或 Rubiyst 的方式?

【问题讨论】:

    标签: ruby arrays


    【解决方案1】:

    对于 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"]]}
    

    【讨论】:

      【解决方案2】:

      这是一个将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 ...
                        }
      

      【讨论】:

      • 感谢 Pesto,也许我应该补充一点,id 可能不是连续的 - 这仍然应该符合您的建议,对吧?我的做法有什么“错误”吗?
      • 我的解决方案不依赖于 id 的顺序或投票的任何特定顺序。您的答案在逻辑上很好,但效率低下。您通过votes_array 创建另一个仅包含第一个字符的数组。然后通过该数组生成唯一条目。然后你通过 that 数组,并且对于每个项目,你再次通过votes_array。在您的情况下,这可能不是一个实际问题,但值得一提。我只通过votes_array 一次。
      【解决方案3】:

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

      # 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 中将符号用于哈希键是有利的,因为对于此类应用程序,它们通常比字符串更有效。

      【讨论】:

      • 我想过做类似的事情,但这不会产生所要求格式的输出。
      • 我只是想做出“一种更优雅、更清洁或 Rubiyst 方式”的解决方案! :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 2020-10-02
      • 1970-01-01
      • 2013-02-22
      • 1970-01-01
      相关资源
      最近更新 更多