Ruby Reminder: Array Subtraction
Just a reminder when working with arrays of objects generated with Active Record.
[Model.find(1), Model.find(2), Model.find(3)] - [Model.find(1)] != [Model.find(2), Model.find(3)]
This does not behave as you would expect, because array subtraction compares elements on their object ids. Each find generates a new object, with a new id, so subtraction does not work. To get the behavior desired, do this instead:
to_be_removed = [Model.find(1)].map{|m| m.id}
[Model.find(1), Model.find(2), Model.find(3)].
delete_if{|m| to_be_removed.include?(m.id)}
It’s not as beautiful, but it gets the job done.
kajinski said,
February 22, 2008 @ 12:05 pm
apparently this is also true with arrays containing hashes. if you create two arrays with an identical hash element in each, subtraction fails:
>> arr1 = [{:foo=>'bar'}]
=> [{:foo=>"bar"}]
>> arr2 = [{:foo=>'bar'}]
=> [{:foo=>"bar"}]
>> arr1 == arr2
=> true
>> arr1[0] == arr2[0]
=> true
>> newarr = arr1 – arr2
=> [{:foo=>"bar"}]