Subtracting one Array from another in Ruby

RubyArraysArray Difference

Ruby Problem Overview


I've got two arrays of Tasks - created and assigned. I want to remove all assigned tasks from the array of created tasks. Here's my working, but messy, code:

	@assigned_tasks = @user.assigned_tasks
	@created_tasks = @user.created_tasks
	
	#Do not show created tasks assigned to self
	@created_not_doing_tasks = Array.new
	@created_tasks.each do |task|
		unless @assigned_tasks.include?(task)
			@created_not_doing_tasks << task
		end
	end

I'm sure there's a better way. What is it? Thanks :-)

Ruby Solutions


Solution 1 - Ruby

You can subtract arrays in Ruby:

[1,2,3,4,5] - [1,3,4]  #=> [2,5]

> ary - other_ary → new_ary Array Difference > > Returns a new array that is a copy of the original array, removing any > items that also appear in other_ary. The order is preserved from the > original array. > > It compares elements using their hash and eql? methods for efficiency. > > [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ] > > If you need > set-like behavior, see the library class Set.

See the Array documentation.

Solution 2 - Ruby

The above solution

a - b

deletes all instances of elements in array b from array a.

[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ]  #=>  [ 3, 3, 5 ]

In some cases, you want the result to be [1, 2, 3, 3, 5]. That is, you don't want to delete all duplicates, but only the elements individually.

You could achieve this by

class Array
  def delete_elements_in(ary)
    ary.each do |x|
      if index = index(x)
        delete_at(index)
      end
    end
  end
end

test

irb(main):198:0> a = [ 1, 1, 2, 2, 3, 3, 4, 5 ]
=> [1, 1, 2, 2, 3, 3, 4, 5]
irb(main):199:0> b = [ 1, 2, 4 ]
=> [1, 2, 4]
irb(main):200:0> a.delete_elements_in(b)
=> [1, 2, 4]
irb(main):201:0> a
=> [1, 2, 3, 3, 5]

The code works even when the two arrays are not sorted. In the example, the arrays are sorted, but this is not required.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondoctororangeView Question on Stackoverflow
Solution 1 - RubyhobodaveView Answer on Stackoverflow
Solution 2 - RubyZack XuView Answer on Stackoverflow