【问题标题】:Filter to exclude elements from array过滤以从数组中排除元素
【发布时间】:2015-09-07 10:09:21
【问题描述】:

试图从数组中过滤一些条目。不能保证它们在主数组中,所以我正在通过迭代进行测试。

total = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
hide = ['charlie', 'echo']

pick = []
for i in total
  if !hide.include?(i)
    puts i
    pick.push(i)
  end
end
puts pick

这行不通。有没有更好的方法来提供这种过滤器?

【问题讨论】:

  • 不工作是什么意思?我觉得没问题...您的预期反应是什么?

标签: arrays ruby


【解决方案1】:

Ruby 允许您在两个数组上使用公共实例方法来获取它们相交或互斥的元素:

a1 = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
a2  = ['charlie', 'echo']
puts a1 - a2
=>  ['alpha', 'bravo', 'delta']

puts a1 & a2
=>  ['charlie', 'echo']

更多信息请查看rubydoc Array。您很可能会在那里找到您真正需要的东西。

【讨论】:

  • 好吧,我不知道你能做到这一点。这是一个有用的方法。我来自一种你几乎必须自己编写的语言。做得很好。谢谢。
  • 更新日期:只是补充一点,在 Ruby 2.6 中,有一些新方法可以更好地访问数组中的交叉点等。快乐的日子。
【解决方案2】:

数组#排除(Rails 6+)

如果您使用的是 Rails(或独立的 ActiveSupport),从版本 6 开始,有一个 Array#excluding 方法可以返回不包括指定元素的数组副本。

["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
[ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]

所以,你的例子可以改写如下:

total = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
hide = ['charlie', 'echo']

pick = total.excluding(hide)
# => ['alpha', 'bravo', 'delta']

【讨论】:

    【解决方案3】:

    .select/reject 怎么样?还是变异版.select!/reject!

    这里是docs

    用法:

    [0, 1, 2, 3].select { |x| x > 1 }
    # output: [2, 3]
    

    或者在你的情况下:

    excluded = [0, 1]
    [0, 1, 2, 3].reject { |x| excluded.include?(x) }
    # output: [2, 3]
    

    【讨论】:

      【解决方案4】:

      您的代码对我有用。 至于“更好的方式”,你可以使用Array#reject

      total = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
      hide = ['charlie', 'echo']
      
      pick = total.reject do |i|
        hide.include?(i)
      end
      puts pick
      

      不仅它更惯用,而且 Ruby 的 for i in collection 循环是根据 collection.each { |i| } 实现的。带有块的方法几乎总是更好的选择。

      【讨论】:

      • 我是 Ruby 新手。那你会如何解释那个块呢?我一直将这些块视为迭代器,而不是在这里呈现的方式。
      • @Rich_F 'reject' 是这里的关键,查看文档,您会发现可以传递一个块来拒绝,并且它将返回一个“新”列表。
      • @TheF 是的,我明白了。我只是对惯用点很感兴趣,因为它在我脑海中的记录不同。 “拒绝此数组中与‘隐藏’中的匹配的那些”。释义是我感兴趣的。你能用“做”这个词来解释这一切,这样清楚吗?我使用积木已经有一段时间了,但是“do”是一个令人困惑的项目。
      • 不确定你的意思。 do 只是一个 Ruby 关键字来打开一个块。您可以使用do - end{ },前者更习惯于多行块,后者通常用于单行。
      • 如果您只是想要一个人性化的解释,那么您应该查看文档。他们说得很清楚:“返回一个新数组,其中包含给定块不正确的 self 中的项目”。您应该熟悉文档中使用的术语和风格,因为它们非常好。
      【解决方案5】:

      如果版本 rails

      class Array
       def excluding(array = [])
        self - array
       end
      end
      

      【讨论】:

      • 没有 Rails,只有核心 Ruby。
      猜你喜欢
      • 2016-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 2011-01-11
      • 2023-02-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多