31

作为 Ruby 的新手,我对 .reject 之间的区别有疑问!和 .delete_if 处理哈希和数组时的方法。如果只是想摆脱某些对象,这些方法在功能上是否有区别?以及使用其中一个的理由?

谢谢!

编辑 我已经阅读了文档......我想我应该在我原来的问题中更清楚。我想知道更多关于效率的差异。他们删除项目的方式是否不同?(同样,忽略返回值。我知道这是一个区别。谢谢!)

4

3 回答 3

60
  • reject- 创建一个没有匹配元素的新数组并返回新数组
  • delete_if- 从当前数组中删除匹配的元素并返回数组
  • reject!- 从当前数组中删除匹配的元素。如果某些内容被拒绝,或者nil没有,则返回数组。
于 2014-07-09T14:20:20.977 回答
20

文档对此非常清楚。

不同的是,如果reject!不更改数组,则返回nil. delete_if将返回未更改的数组。

于 2013-09-20T16:48:31.043 回答
5

tl; dr:delete_if似乎稍微快一点。但是,正如其他答案中所指出的,选择方法的主要考虑因素是返回值的差异。

既然你澄清了你的问题是关于效率的,我做了一些测试:

> time { (1..100000).to_a.reject!{ |n| n % 5 == 0 } }
  0.390000   0.000000   0.390000 (  0.394596)
> time { (1..100000).to_a.delete_if{ |n| n % 5 == 0 } }
  0.400000   0.000000   0.400000 (  0.399122)

> time { (1..200000).to_a.reject!{ |n| n % 5 == 0 } }
  1.650000   0.000000   1.650000 (  1.657927)
> time { (1..200000).to_a.delete_if{ |n| n % 5 == 0 } }
  1.630000   0.010000   1.640000 (  1.637719)

> time { (1..300000).to_a.reject!{ |n| n % 5 == 0 } }
  3.700000   0.000000   3.700000 (  3.717206)
> time { (1..300000).to_a.delete_if{ |n| n % 5 == 0 } }
  3.660000   0.000000   3.660000 (  3.686213)

> time { (1..400000).to_a.reject!{ |n| n % 5 == 0 } }
  7.320000   0.020000   7.340000 (  7.361767)
> time { (1..400000).to_a.delete_if{ |n| n % 5 == 0 } }
  7.190000   0.020000   7.210000 (  7.239549)

所以,看起来超过一定尺寸delete_if会稍微快一些。 time定义为:

def time(&block)
  puts Benchmark.measure(&block)
end

这些数字分别代表用户 CPU 时间、系统 CPU 时间、用户和系统 CPU 时间的总和以及经过的实际时间。您可以在此处找到对它们含义的解释。请注意,与每个基准测试 YMMV 一样,您应该测试您的特定工作流程,而不是我设计的删除 5 的倍数的示例。

于 2016-02-21T13:46:28.660 回答