From bfaa3091c3c32b5980a614ef0f7b39cbf83f6db3 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 5 Mar 2019 16:04:41 -0800 Subject: Added Array#including, Array#excluding, Enumerable#including, Enumerable#excluding --- .../lib/active_support/core_ext/array/access.rb | 20 ++++++++++++---- .../lib/active_support/core_ext/enumerable.rb | 28 ++++++++++++++++++---- 2 files changed, 40 insertions(+), 8 deletions(-) (limited to 'activesupport/lib/active_support/core_ext') diff --git a/activesupport/lib/active_support/core_ext/array/access.rb b/activesupport/lib/active_support/core_ext/array/access.rb index b7ff7a3907..c9eecc55f9 100644 --- a/activesupport/lib/active_support/core_ext/array/access.rb +++ b/activesupport/lib/active_support/core_ext/array/access.rb @@ -29,16 +29,28 @@ class Array end end - # Returns a copy of the Array without the specified elements. + # Returns a new array that includes the passed elements. + # + # Example: [ 1, 2, 3 ].including(4, 5) => [ 1, 2, 3, 4, 5 ] + def including(*elements) + self + elements.flatten + end + + # Returns a copy of the Array excluding the specified elements. # # people = ["David", "Rafael", "Aaron", "Todd"] - # people.without "Aaron", "Todd" + # people.excluding "Aaron", "Todd" # # => ["David", "Rafael"] # - # Note: This is an optimization of Enumerable#without that uses Array#- + # Note: This is an optimization of Enumerable#excluding that uses Array#- # instead of Array#reject for performance reasons. + def excluding(*elements) + self - elements.flatten + end + + # Alias for #excluding. def without(*elements) - self - elements + excluding(*elements) end # Equal to self[1]. diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index d87d63f287..d6fb89e588 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -97,23 +97,43 @@ module Enumerable end end + # Returns a new array that includes the passed elements. + # + # [ 1, 2, 3 ].including(4, 5) + # # => [ 1, 2, 3, 4, 5 ] + # + # ["David", "Rafael"].including %w[ Aaron Todd ] + # # => ["David", "Rafael", "Aaron", "Todd"] + def including(*elements) + to_a.including(*elements) + end + # The negative of the Enumerable#include?. Returns +true+ if the # collection does not include the object. def exclude?(object) !include?(object) end - # Returns a copy of the enumerable without the specified elements. + # Returns a copy of the enumerable excluding the specified elements. + # + # ["David", "Rafael", "Aaron", "Todd"].excluding "Aaron", "Todd" + # # => ["David", "Rafael"] # - # ["David", "Rafael", "Aaron", "Todd"].without "Aaron", "Todd" + # ["David", "Rafael", "Aaron", "Todd"].excluding %w[ Aaron Todd ] # # => ["David", "Rafael"] # - # {foo: 1, bar: 2, baz: 3}.without :bar + # {foo: 1, bar: 2, baz: 3}.excluding :bar # # => {foo: 1, baz: 3} - def without(*elements) + def excluding(*elements) + elements.flatten! reject { |element| elements.include?(element) } end + # Alias for #excluding. + def without(*elements) + excluding(*elements) + end + # Convert an enumerable to an array based on the given key. # # [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name) -- cgit v1.2.3