使用.include?防止重复

时间:2015-07-19 20:55:14

标签: ruby

我对如何使用.include?以防止重复项加入列表感到有点困惑。

我首先被要求将一个项目附加到列表中。

def add_item!(item, list)
  list << item
end

然后我需要使用.include?来防止重复。我的尝试:

def add_item!(item, list)
  list << item
  list.include?(item)
end

3 个答案:

答案 0 :(得分:3)

你可以这样使用它:

def add_item!(item, list)
  list << item unless list.include?(item)
end

在上面的代码中,在将项目添加到列表之前,#include?被称为。如果该项目已在列表中,则#include?将返回true,并且将跳过将该项目添加到列表中的代码。

答案 1 :(得分:2)

如果你想把代码放在一个方法中,你必须考虑到Ruby通过值而不是通过引用传递参数。为什么在第一种情况下这似乎有效,我不知道,可能本身就是一个问题。所以我结束了第一个方法的名称! (到位)但不是其他两个。

我用三种不同的方法和包括做了一些基准测试?解决方案显然胜出放置数组的初始值需要花费时间,但所有解决方案都必须这样做,因此您可以放弃它。

require 'set'
require 'benchmark'

def add_item1!(item, list)
  list << item unless list.include?(item)
end

def add_item2(item, list)
  list |= [item]
end

def add_item3(item, list)
  set = Set.new(list)
  set << item
  list = set.to_a
end

array1 = [3,2,1,4]
add_item1!(2, array1) # [3, 2, 1, 4]
add_item1!(5, array1) # [3, 2, 1, 4, 5]

array2 = [3,2,1,4]
array2 = add_item2(2, array2) # [3, 2, 1, 4]
array2 = add_item2(5, array2) # [3, 2, 1, 4, 5]

array3 = [3,2,1,4]
array3 = add_item3(2, array3) # [3, 2, 1, 4]
array3 = add_item3(5, array3) # [3, 2, 1, 4, 5]

TESTS = 100000
Benchmark.bmbm do |results|
  results.report("unless not new") {TESTS.times {array1 = [3,2,1,4];add_item1!(2, array1) }}
  results.report("unless new")     {TESTS.times{array1 = [3,2,1,4];add_item1!(5, array1) }}
  results.report("|= not new")     {TESTS.times{array2 = [3,2,1,4];array2 = add_item2(2, array2) }}
  results.report("|= new")         {TESTS.times{array2 = [3,2,1,4];array2 = add_item2(5, array2) }}
  results.report("Set not new")    {TESTS.times{array3 = [3,2,1,4];array3 = add_item3(2, array3) }}
  results.report("Set new")        {TESTS.times{array3 = [3,2,1,4];array3 = add_item3(5, array3) }}
end

#                      user     system      total        real
# unless not new   0.031000   0.000000   0.031000 (  0.027002)
# unless new       0.047000   0.000000   0.047000 (  0.052003)
# |= not new       0.125000   0.000000   0.125000 (  0.118007)
# |= new           0.125000   0.000000   0.125000 (  0.126007)
# Set not new      0.358000   0.000000   0.358000 (  0.354020)
# Set new          0.359000   0.000000   0.359000 (  0.364021)

答案 2 :(得分:0)

你只想维护你的阵列而你不知道是否添加了这个元素你可以做到这一点

def add_item!(item, list)
  list = list | [item]
end

在这里你可以找到一个例子。

2.2.1 :001 > [1,2]
 => [1, 2] 
2.2.1 :002 > [1,2] | [1]
 => [1, 2] 
2.2.1 :003 > [1,2] | [1,3]
 => [1, 2, 3] 
2.2.1 :004 > 
  

ary | other_ary→new_ary

     

Set Union - 通过将ary与other_ary连接来返回一个新数组,不包括&gt;任何重复并保留原始数组的顺序。

但如果你想知道该元素是否被拒绝,你可以做

def add_item!(item, list)
  list << item unless list.include?(item)
end