From d37865248e925629f4b2e835ce5b7b86309aa6de Mon Sep 17 00:00:00 2001 From: Nicolas Cavigneaux Date: Wed, 16 Mar 2011 11:59:48 +0100 Subject: [PATCH 1/2] Add Enumerable#uniq? to check if an Enumerable has no duplicated content --- .../lib/active_support/core_ext/enumerable.rb | 10 ++++++++++ activesupport/test/core_ext/enumerable_test.rb | 12 ++++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index 6d7f771..6d4dd56 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -99,6 +99,16 @@ module Enumerable size = block_given? ? select(&block).size : self.size size > 1 end + + # Returns true if the collection has no duplicated content. + # Can be called with a block too, much like any?, so people.uniq? { |p| p.age > 26 } returns true if only 1 person is over 26. + def uniq?(&block) + if block_given? + select(&block).uniq.size == select(&block).size + else + uniq.size == size + end + end # The negative of the Enumerable#include?. Returns true if the collection does not include the object. def exclude?(object) diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb index 4655bfe..f310b3b 100644 --- a/activesupport/test/core_ext/enumerable_test.rb +++ b/activesupport/test/core_ext/enumerable_test.rb @@ -90,6 +90,18 @@ class EnumerableTests < Test::Unit::TestCase assert [ 1, 2, 2 ].many? {|x| x > 1 } end + def test_uniq + assert [].uniq? + assert [ 1 ].uniq? + assert [ 1, 2 ].uniq? + assert ![ 1, 1 ].uniq? + + assert [].uniq? { |x| x > 1 } + assert [ 2 ].uniq? { |x| x > 1 } + assert [ 1, 2 ].uniq? { |x| x > 1 } + assert ![ 1, 2, 2 ].uniq? { |x| x > 1 } + end + def test_exclude? assert [ 1 ].exclude?(2) assert ![ 1 ].exclude?(1) -- 1.7.3.2 From e163fe5f8aff990b6c9c9ed9227dae957795e9d5 Mon Sep 17 00:00:00 2001 From: Nicolas Cavigneaux Date: Wed, 16 Mar 2011 13:15:30 +0100 Subject: [PATCH 2/2] Add calculation cache to prevent running it multiple times --- .../lib/active_support/core_ext/enumerable.rb | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index 6d4dd56..a60fe82 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -104,7 +104,8 @@ module Enumerable # Can be called with a block too, much like any?, so people.uniq? { |p| p.age > 26 } returns true if only 1 person is over 26. def uniq?(&block) if block_given? - select(&block).uniq.size == select(&block).size + collection = select(&block) + collection.uniq.size == collection.size else uniq.size == size end -- 1.7.3.2