从数组中删除重复元素

3

我有两个数组:array1array2,分别如下:

array1 = [ obj11, obj21, obj31 ]
array2 = [ obj21, obj22, obj23 ]

这两个数组中的对象属于同一类。我想检查 array1 是否包含已经存在于 array2 中的对象并将它们删除。

假设 obj11obj22 是相等的。通过“相等”,我指的是它们具有相似的属性值。然后,我想从 array1 中删除 obj11,然后在 array2 中插入 obj21obj31

我已经为对象所属类的属性定义了相等性,可以从这里找到。

def ==(other)
  return self.a == other.a && self.b == other.b
end

生成的数组将会是:
array2 = [ obj21, obj22, obj23, obj21, obj31 ]

1
你目前尝试了什么? - gernberg
请展示一个结果数组的例子。 - the Tin Man
6个回答

3
你可以使用 Array#|(它执行并集操作)来去除重复项。
array1 = ["dog", "cat", "had"]
array2 = ["big", "fight", "had"]
array1 | array2
# => ["dog", "cat", "had", "big", "fight"]

@Arwa 我正在关注你的主题行 如果已存在,则从数组中删除对象。如果你正在处理 Array,则不需要定义自己的。 - Arup Rakshit

2

使用uniq是从多个数组中快速删除重复值的方法。

array1 = ["dog", "cat", "had"]
array2 = ["big", "fight", "had"]

new_array = (array1 + array2).uniq  # <- ["dog", "cat", "had", "big", "fight"]

uniq可以从一个数组中移除重复的值。通过将array1array2组合在一起,您可以过滤掉它们之间的重复项。


1
如果我要逐字解决你的问题,那么我会写出这样的内容:
array1 = [ :obj11, :obj21, :obj31 ]
array2 = [ :obj21, :obj22, :obj23 ]

new_array = (array1 - array2) + array2
p new_array

(array1 - array2) 取出在 array2 中也存在的元素,并将其加入 array2,即可得到最终结果。

输出

[:obj11, :obj31, :obj21, :obj22, :obj23]

(注:我使用符号作为数组元素以进行说明)
(Note: 我使用符号作为数组元素以进行说明)

1
我已经得到答案。接下来,我将从array1中删除已经存在于array2中的内容。这里的相等性是根据我在问题中定义的方式进行比较的。因此,我们会检查方法中所定义的属性是否相等。
array1.delete_if{|elem| array2.any?{|e| e == elem}}

然后将array1的剩余部分添加到array2中。
array2 << array1

然后我将array2压平。
array2.flatten!

好的回答。我建议使用array2.concat(array1)而不是array2 << array1; array2.flatten! - Cary Swoveland
谢谢,我会修改它。 - Arwa

0
另一种方法(使用intersection操作):
   array1 = [ 1, 2, 3, 4, 5 ]
   array2 = [ 2, 3, 4, 5, 6 ]
   final_array = array1 + array2
   final_array & final_array

这也将删除重复项。IRB 输出:

2.2.1 :012 > array1 = [ 1, 2, 3, 4, 5 ]
 => [1, 2, 3, 4, 5] 
2.2.1 :013 > array2 = [ 2, 3, 4, 5, 6 ]
 => [2, 3, 4, 5, 6] 
2.2.1 :014 > final_array = array1 + array2
 => [1, 2, 3, 4, 5, 2, 3, 4, 5, 6] 
2.2.1 :015 > final_array & final_array
 => [1, 2, 3, 4, 5, 6] 

0
你可以按照以下方式实现:
 a2.concat(a1.delete_if { |e| a2.include?(e) })

这是一个例子:

class MyClass
  attr_reader :a, :b, :c
  def initialize(a, b, c)
    @a, @b, @c = a, b, c
  end
  def ==(other)
    self.a == other.a && self.b == other.b
  end
end

a1 = [MyClass.new('cat', 'bat', 'rat'),
      MyClass.new('dog', 'hog', 'pig'),
      MyClass.new('jay', 'bee', 'fly'),]
  #=> [#<MyClass:0x007fca8407b678 @a="cat", @b="bat", @c="rat">,
  #    #<MyClass:0x007fca8407bee8 @a="dog", @b="hog", @c="pig">,
  #    #<MyClass:0x007fca84073ef0 @a="jay", @b="bee", @c="fly">] 
a2 = [MyClass.new('fly', 'bee', 'bat'),
      MyClass.new('cat', 'bat', 'rat'),
      MyClass.new('dog', 'hog', 'cat'),] 
  #=> [#<MyClass:0x007fca840382d8 @a="fly", @b="bee", @c="bat">,
  #    #<MyClass:0x007fca840381e8 @a="cat", @b="bat", @c="rat">,
  #    #<MyClass:0x007fca840380d0 @a="dog", @b="hog", @c="cat">] 

a2.concat(a1.delete_if { |e| a2.include?(e) })
  #=> [#<MyClass:0x007f96d404ea08 @a="fly", @b="bee", @c="bat">,
  #    #<MyClass:0x007f96d404e8c8 @a="cat", @b="bat", @c="rat">,
  #    #<MyClass:0x007f96d404e710 @a="dog", @b="hog", @c="cat">,
  #    #<MyClass:0x007f96d409d9c8 @a="jay", @b="bee", @c="fly">] 
a1
  #=> [#<MyClass:0x007f96d409d9c8 @a="jay", @b="bee", @c="fly">]  

如果我们将a1的第一个元素改为:
 MyClass.new('cat', 'bat', 'rat')

至:

 MyClass.new('cat', 'rat', 'bat')

我们得到:

a2.concat(a1.delete_if { |e| a2.include?(e) })
  #=> [#<MyClass:0x007f89528568c0 @a="fly", @b="bee", @c="bat">,
  #    #<MyClass:0x007f8952856708 @a="cat", @b="bat", @c="rat">,
  #    #<MyClass:0x007f89528562d0 @a="dog", @b="hog", @c="cat">,
  #    #<MyClass:0x007f89519277f0 @a="cat", @b="rat", @c="bat">,
  #    #<MyClass:0x007f8951927598 @a="jay", @b="bee", @c="fly">] 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接