【问题标题】:Ruby code optimization: select from arrayRuby 代码优化:从数组中选择
【发布时间】:2012-12-05 19:23:52
【问题描述】:

假设我们对 SomeClass 进行分类。

class SomeClass < SomeClassThatAssignAttributesOnInitialization
  attr_accessor :group
  attr_accessor :name
end

以及它的实例数组

arr = [SomeClass.new(group:0, name:'one'),
       SomeClass.new(group:0, name:'two'),
       SomeClass.new(group:1, name:'three'),
       SomeClass.new(group:1, name:'four')]

我需要将每个组的第一个元素放入数组中。

现在下一个方法可以使用

current_group = nil
first_elements = arr.map do |instance|
  if current_group != instance.group
    current_group = instance.group
    instance.name
  end
end

这很好用,但我认为有某种“Ruby”方法可以做到这一点。

谁能帮帮我?

谢谢

【问题讨论】:

标签: ruby arrays algorithm


【解决方案1】:

Ruby 在Enumerable 对象上有一个方便的group_by 方法,它返回一个Hash

arr.group_by(&:group)
# => {0=>[#<SomeClass group=0, name="one">, #<SomeClass group=0, name="two">], 1=>[#<SomeClass group=1, name="three">, #<SomeClass group=1, name="four">]}

所以只需将一些方法链接到最后:

arr.group_by(&:group).values.map {|vs| vs[0].name}
# => ["one", "three"]

【讨论】:

    【解决方案2】:
    arr.group_by(&:group).values.map(&:first)
    

    【讨论】:

      【解决方案3】:

      为什么不只是:

      first_elements = arr.map(&:name)
      

      【讨论】:

      • 我需要从每个组的第一个元素中取名字。您的示例将从所有元素中获取名称
      • 是的,很抱歉 - 我在写完答案后注意到了这一点。
      【解决方案4】:
      SomeClass = Struct.new(:group, :name)
      
      arr = [
        SomeClass.new(0, 'one'),
        SomeClass.new(0, 'two'),
        SomeClass.new(1, 'three'),
        SomeClass.new(1, 'four')
      ]
      
      arr.group_by(&:group).values.map(&:first)
      # => [
      #   #<struct SomeClass group=0, name="one">,
      #   #<struct SomeClass group=1, name="three">
      # ]
      

      或者只获取名称:

      arr.group_by(&:group).values.map(&:first).map(&:name)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-16
        • 1970-01-01
        • 2020-06-09
        • 2014-11-17
        • 1970-01-01
        • 1970-01-01
        • 2018-01-26
        相关资源
        最近更新 更多