Ruby .reject! vs .delete_if

作为Ruby的新手,我对.reject之间的区别有疑问! 和.delete_if处理哈希和数组时的方法。 如果只是想摆脱某些对象,那么这些方法之间是否存在function上的差异? 有理由使用一个而不是另一个吗?

谢谢!

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

文档非常明确。

不同的是,如果reject! 不更改数组,它返回nildelete_if将返回未更改的数组。

  • reject – 创建一个没有匹配的元素并返回新数组的新数组
  • delete_if – 删除与当前数组匹配的元素并返回该数组
  • reject! – 删除与当前数组匹配的元素。 如果某些内容被拒绝,则返回该数组,否则返回nil

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的倍数的设计示例。