From: Hugh Sasse Staff Elec Eng Date: 2001-06-21T23:41:27+09:00 Subject: [ruby-talk:16706] Re: bag difference On Thu, 21 Jun 2001, HarryO wrote: > In article , "Niklas > Frykholm" wrote: > > > > I plan to read this carefully when I have time, but here's what I came up > with. It's slightly more verbose, but I think an Array#delete_first() > would be useful, which is a bonus. How efficient it is depends on how > efficient Array#index and Array#delete_at are, but I would guess they're > very simple. > > class Array > > def delete_first(x) > > if (i = self.index(x)) > self.delete_at(i) > end > > end > > def bag_minus(other) > > difference = Array.new > unwanted = other.clone > > self.each do |x| > if !unwanted.delete_first(x) > difference.push(x) > end > end > > return difference > end > > end > > a = [0,0,1,1,1,2,2,3,3,3,3,4,4,5,5,6] > b = [1,2,3,3,4] > > puts "#{a}.bag_minus(#{b}) = #{a.bag_minus(b)}" # --> > [0,0,1,1,2,3,3,4,5,5,6] > Thank you. I was a bit confused by the other solution too, but it seemed to rely on going through the array more than once. Anyway, I settled on this: #!/usr/local/bin/ruby -w class Array def bag_subtract!(other) other.each { |value| i = index(value) delete_at(i) if i } self end end if __FILE__ == $0 require "runit/testcase" require 'runit/cui/testrunner' require 'runit/testsuite' class Testing_class < RUNIT::TestCase def test_feature1 mine = [1,1,2,3,3,3,4,4,4,5] other = [1,2,3,4,4,6] assert_equal([1,3,3,4,5],mine.bag_subtract!(other)) # ... etc end #... end RUNIT::CUI::TestRunner.run(Testing_class.suite) end Thank you all, Hugh