Added Array#including, Array#excluding, Enumerable#including, Enumerable#excluding

上级 91ed21b3
* Allow Array#excluding and Enumerable#excluding to deal with a passed array gracefully.
[ 1, 2, 3, 4, 5 ].excluding([4, 5]) => [ 1, 2, 3 ]
*DHH*
* Renamed Array#without and Enumerable#without to Array#excluding and Enumerable#excluding, to create parity with
Array#including and Enumerable#including. Retained the old names as aliases.
*DHH*
* Added Array#including and Enumerable#including to conveniently enlarge a collection with more members using a method rather than an operator:
[ 1, 2, 3 ].including(4, 5) => [ 1, 2, 3, 4, 5 ]
post.authors.including(Current.person) => All the authors plus the current person!
*DHH*
## Rails 6.0.0.beta2 (February 25, 2019) ##
* New autoloading based on [Zeitwerk](https://github.com/fxn/zeitwerk).
......
......@@ -29,16 +29,28 @@ def to(position)
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 <tt>Enumerable#without</tt> that uses <tt>Array#-</tt>
# Note: This is an optimization of <tt>Enumerable#excluding</tt> that uses <tt>Array#-</tt>
# instead of <tt>Array#reject</tt> for performance reasons.
def excluding(*elements)
self - elements.flatten
end
# Alias for #excluding.
def without(*elements)
self - elements
excluding(*elements)
end
# Equal to <tt>self[1]</tt>.
......
......@@ -97,23 +97,43 @@ def many?
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 <tt>Enumerable#include?</tt>. 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)
......
......@@ -32,6 +32,16 @@ def test_specific_accessor
assert_equal array[-2], array.second_to_last
end
def test_including
assert_equal [1, 2, 3, 4, 5], [1, 2, 4].including(3, 5).sort
assert_equal [1, 2, 3, 4, 5], [1, 2, 4].including([3, 5]).sort
end
def test_excluding
assert_equal [1, 2, 4], [1, 2, 3, 4, 5].excluding(3, 5)
assert_equal [1, 2, 4], [1, 2, 3, 4, 5].excluding([3, 5])
end
def test_without
assert_equal [1, 2, 4], [1, 2, 3, 4, 5].without(3, 5)
end
......
......@@ -217,11 +217,17 @@ def test_exclude?
assert_equal false, GenericEnumerable.new([ 1 ]).exclude?(1)
end
def test_excluding
assert_equal [1, 2, 4], GenericEnumerable.new((1..5).to_a).excluding(3, 5)
assert_equal [3, 4, 5], GenericEnumerable.new((1..5).to_a).excluding([1, 2])
assert_equal [1, 2, 4], (1..5).to_a.excluding(3, 5)
assert_equal [1, 2, 4], (1..5).to_set.excluding(3, 5)
assert_equal({ foo: 1, baz: 3 }, { foo: 1, bar: 2, baz: 3 }.excluding(:bar))
end
def test_without
assert_equal [1, 2, 4], GenericEnumerable.new((1..5).to_a).without(3, 5)
assert_equal [1, 2, 4], (1..5).to_a.without(3, 5)
assert_equal [1, 2, 4], (1..5).to_set.without(3, 5)
assert_equal({ foo: 1, baz: 3 }, { foo: 1, bar: 2, baz: 3 }.without(:bar))
assert_equal [3, 4, 5], GenericEnumerable.new((1..5).to_a).without([1, 2])
end
def test_pluck
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册