3

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 ]
2
  • 1
    What have you attempted so far? Commented Jul 29, 2015 at 16:44
  • Show us an example of what your resulting array will be. Commented Jul 29, 2015 at 17:19

6 Answers 6

3

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"]
Sign up to request clarification or add additional context in comments.

1 Comment

@Arwa I was following your subject line Delete object from array if already exist.. If you are dealing with Array, not need to define your own.
2

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.

Comments

1

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)

Comments

1

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!

2 Comments

Good answer. Rather than array2 << array1; array2.flatten! I would suggest array2.concat(array1).
Thanks, I will change it.
0

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

Comments

0

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] 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.