Last active
August 29, 2015 13:55
-
-
Save jah2488/8689010 to your computer and use it in GitHub Desktop.
Non-destructively perform a difference operation on two arrays
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def diff(a,b) | |
hash_by_count(a) | |
.merge(hash_by_count(b)) { |_, av, bv| av - bv } | |
.flat_map { |k, v| [k] * v } | |
end | |
private | |
def hash_by_count(arr) | |
Hash[arr.group_by { |x| x }.map { |k, v| [k, v.count] }] | |
end | |
if $0 !~ /rspec/ | |
p diff([1,1,1], [1,1]) | |
p diff([1,2,1], [1,1]) | |
p diff([1,2,1], [2]) | |
p diff([1,2,1], [1]) | |
else | |
describe 'diff' do | |
it 'removes difference between arrs' do | |
expect(diff([1,1,1], [1,1])).to eq [1] | |
expect(diff([1,2,1], [1,1])).to eq [2] | |
expect(diff([1,2,1], [2])).to eq [1,1] | |
expect(diff([1,2,1], [1])).to eq [1,2] | |
end | |
it 'should work with non ints' do | |
expect(diff([:foo, :bar, :foo], [:foo])).to eq [:foo, :bar] | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Array | |
def -(other) | |
hash_by_count(self) | |
.merge(hash_by_count(other)) { |_, selfv, otherv| selfv - otherv } | |
.flat_map { |k, v| [k] * v } | |
end | |
private | |
def hash_by_count(arr) | |
Hash[arr.group_by { |x| x }.map { |k, v| [k, v.count] }] | |
end | |
end | |
[1,1,1] - [1,1] == [1] | |
[1,2,1] - [1] == [1,2] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Someone was wondering what was going on with
arr.group_by { |x| x }
and thats probably worth explaining a little. This is simply a way of telling ruby to group by self. This isn't normally very useful unless you are dealing with duplicates, where it will group them together into an array. This effect can be duplicated withgroup_by(&:to_s)
, but converts all your keys to strings in the process and doesn't work well if you want to preserve the original type.