【问题标题】:Find set of objects in array that have same attributes在数组中查找具有相同属性的对象集
【发布时间】:2014-05-05 09:35:09
【问题描述】:

假设我有一个包含两个属性的数组:'n_parents''class',看起来像这样:

my_arr = [{n_parents: 10, class: 'right'}, {n_parents: 10, class: 'right'}, {n_parents: 5, class: 'left'}, {n_parents: 2, class: 'center'}, {n_parents: 2, class: 'center'}, {n_parents: 2, class: 'center'}]

我想得到一个数组,其中的对象共享这两个属性中的大部分。所以在前面的例子中:

result = [{n_parents: 2, class: 'center'}, {n_parents: 2, class: 'center'}, {n_parents: 2, class: 'center'}]

因为有三个对象共享n_parents = 2class = 'center'

到目前为止,我知道如何按 dos 两个属性进行分组,但之后我不确定如何获取具有更多元素的集合。

现在我有:

my_arr.group_by { |x| [x[:n_parents], x[:class]] }

【问题讨论】:

    标签: ruby arrays enumerable


    【解决方案1】:

    这应该适合你。它通过散列本身对散列进行分组,然后通过数组计数获得最大的组

     my_arr = [{n_parents: 10, class: 'right'}, {n_parents: 10, class: 'right'}, {n_parents: 5, class: 'left'}, {n_parents: 2, class: 'center'}, {n_parents: 2, class: 'center'}, {n_parents: 2, class: 'center'}]
     my_arr.group_by { |h| h }.max_by { |h,v| v.count }.last
     #=>[{:n_parents=>2, :class=>"center"}, {:n_parents=>2, :class=>"center"}, {:n_parents=>2, :class=>"center"}]
    

    【讨论】:

    • 你最后错过了#last。所以我在想,没有方法,你是如何得到输出的.. ;)
    • @ArupRakshit 我注意到并添加了它为什么需要添加空格?清晰度?
    • 当然,作为Ruby爱好者喜欢这样写。见here..
    • 好吧,我只是想知道,因为它显然适用于任何一种方式。我也是一个巨大的红宝石爱好者,我最喜欢的部分是语法几乎是空白无知。 (我不那么喜欢 Python 的主要原因)
    【解决方案2】:

    如下所示:

    my_arr.group_by(&:values).max_by { |_,v| v.size }.last
    # => [{:n_parents=>2, :class=>"center"},
    #     {:n_parents=>2, :class=>"center"},
    #     {:n_parents=>2, :class=>"center"}]
    

    【讨论】:

      【解决方案3】:

      我正在使用 OP 使用的代码并对其进行扩展以获得他想要的结果:--

      my_arr.group_by { |x| [x[:n_parents], x[:class]] }.max_by{|k,v| v.size}.last
      

      输出

      #=> [{:n_parents=>2, :class=>"center"}, {:n_parents=>2, :class=>"center"}, {:n_parents=>2, :class=>"center"}]
      

      【讨论】:

        【解决方案4】:

        这是要发布的第四个答案。之前的三个答案都使用了group_by/max_by/last。当然,这可能是最好的方法,但它是最有趣、最有趣的吗?以下是生成所需结果的其他几种方法。当

        my_arr = [{n_parents: 10, class: 'right' }, {n_parents: 10, class: 'right' },
                  {n_parents:  5, class: 'left'  }, {n_parents:  2, class: 'center'},
                  {n_parents:  2, class: 'center'}, {n_parents:  2, class: 'center'}]
        

        想要的结果是:

          #=> [{:n_parents=>2, :class=>"center"},
          #    {:n_parents=>2, :class=>"center"},
          #    {:n_parents=>2, :class=>"center"}]
        

        #1

        # Create a hash `g` whose keys are the elements of `my_arr` (hashes)
        # and whose values are counts for the elements of `my_arr`.
        # `max_by` the values (counts) and construct the array. 
        
        el, nbr = my_arr.each_with_object({}) { |h,g| g[h] = (g[h] ||= 0) + 1 }
                        .max_by { |_,v| v } 
        arr = [el]*nbr
        

        #2

        # Sequentially delete the elements equal to the first element of `arr`,
        # each time calculating the number of elements deleted, by determining
        # `arr.size` before and after the deletion. Compare that number with the
        # largest number deleted so far to find the element with the maximum
        # number of instances in `arr`, then construct the array. 
        
        arr = my_arr.map(&:dup)
        most_plentiful = { nbr_copies: 0, element: [] }
        until arr.empty? do
          sz = arr.size
          element = arr.delete(arr.first)
          if sz - arr.size > most_plentiful[:nbr_copies]
            most_plentiful = { nbr_copies: sz - arr.size, element: element }
          end
        end
        arr = [most_plentiful[:element]]* most_plentiful[:nbr_copies]
        

        【讨论】:

        • 是的,您的代码确实有效,并且是一种有趣的方法,但与此同时,由于缺乏其他答案的简洁性和可读性,它将被重构。
        • @engineersmnky,我同意 100%。如果这是现实生活,我会像其他人一样使用 group_by/max_by。然而,通过尝试为 SO 问题想出不同的、有时是非常规的解决方案,我学到了很多关于 Ruby 的知识,尤其是当我迟到的时候,就像这里一样。我发布这些沉思是希望它们具有一定的教育价值。试试看!
        猜你喜欢
        • 2018-11-03
        • 1970-01-01
        • 2021-07-17
        • 2014-11-22
        • 1970-01-01
        • 1970-01-01
        • 2013-10-14
        • 2023-03-26
        相关资源
        最近更新 更多