diff options
author | Florian Ebeling <florian.ebeling@gmail.com> | 2018-09-27 10:19:08 +0200 |
---|---|---|
committer | Florian Ebeling <florian.ebeling@gmail.com> | 2018-11-06 17:56:58 +0100 |
commit | f9157587c9d61a0e24a0dcba7b31aa698ddeb641 (patch) | |
tree | c66767b93098e9e8c614431438e134c262e14878 /activerecord/lib | |
parent | 11bad94237b17c078eb5cac8557e9ed9e37ec274 (diff) | |
download | rails-f9157587c9d61a0e24a0dcba7b31aa698ddeb641.tar.gz rails-f9157587c9d61a0e24a0dcba7b31aa698ddeb641.tar.bz2 rails-f9157587c9d61a0e24a0dcba7b31aa698ddeb641.zip |
Optimize difference and intersection
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/associations/has_many_through_association.rb | 26 |
1 files changed, 9 insertions, 17 deletions
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 8a8149b777..2322a49931 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -164,32 +164,24 @@ module ActiveRecord end def difference(a, b) - set_a = as_set(a) - set_b = as_set(b) + distribution = distribution(b) - from_set(set_a - set_b) + a.reject { |record| mark_occurrence(distribution, record) } end def intersection(a, b) - set_a = as_set(a) - set_b = as_set(b) + distribution = distribution(b) - from_set(set_a & set_b) + a.select { |record| mark_occurrence(distribution, record) } end - def as_set(records) - records.zip(occurences(records)) + def mark_occurrence(distribution, record) + distribution[record] > 0 && distribution[record] -= 1 end - def from_set(record_set) - record_set.map(&:first) - end - - def occurences(array) - counts = Hash.new(0) - - array.map do |object| - counts[object] += 1 + def distribution(array) + array.each_with_object(Hash.new(0)) do |record, distribution| + distribution[record] += 1 end end |