Arwa
Arwa

Reputation: 587

Delete duplicate elements from Array

I have two arrays, array1 and array2, as follows:

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

Objects in both arrays are from the same class. I want to check if array1 contains objects that already exist in array2 and delete them.

Let's say obj11 and obj22 are equal. By "equal," I mean they have similar attribute values. Then I would like to delete obj11 from array1, then insert obj21 and obj31 in array2.

I already define equality for attributes in the objects' class from here:

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

The resulting array would be:

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

Upvotes: 3

Views: 101

Answers (6)

K M Rakibul Islam
K M Rakibul Islam

Reputation: 34338

Another way (using intersection operation):

   array1 = [ 1, 2, 3, 4, 5 ]
   array2 = [ 2, 3, 4, 5, 6 ]
   final_array = array1 + array2
   final_array & final_array

This will also delete duplicates. IRB output:

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] 

Upvotes: 0

Cary Swoveland
Cary Swoveland

Reputation: 110685

You could do that as follows:

 a2.concat(a1.delete_if { |e| a2.include?(e) })

Here's an example:

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">]  

If we change the first element of a1 from:

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

to:

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

we obtain:

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">] 

Upvotes: 0

Arwa
Arwa

Reputation: 587

I got the answer. In the following I delete from array1 what is already exist in array2. Equality here works as I define it in the question. Thus, checking if attributes (that have been defined in the method ==) are equal.

array1.delete_if{|elem| array2.any?{|e| e == elem}}

Then add the rest of array1 into array2.

array2 << array1

Then I flatten array2.

array2.flatten!

Upvotes: 1

Wand Maker
Wand Maker

Reputation: 18762

If I want to solve your problem literally, then, I will write something like this:

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

new_array = (array1 - array2) + array2
p new_array

(array1 - array2) takes those elements from array1 that are also present in array2 and adding array2 to that will get you the final result

Output

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

(Note: I used symbols as elements of arrays for illustration purposes)

Upvotes: 1

Arup Rakshit
Arup Rakshit

Reputation: 118271

You can use Array#| ( it does union operation) to remove duplicates too.

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

Upvotes: 3

Wes Foster
Wes Foster

Reputation: 8900

A quick way to remove duplicate values from multiple arrays is by using uniq

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

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

uniq removes duplicate values from an array. By combining array1 and array2 together, you can then filter out duplicates between the two of them.

Upvotes: 2

Related Questions