Add `Array#extract!`

The method removes and returns the elements for which the block returns a true value.
If no block is given, an Enumerator is returned instead.

```
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
numbers # => [0, 2, 4, 6, 8]
```
This commit is contained in:
bogdanvlviv 2018-06-14 22:24:45 +03:00
parent ffc4703f22
commit 77b0126054
No known key found for this signature in database
GPG Key ID: E4ACD76A6DB6DFDD
5 changed files with 90 additions and 0 deletions

View File

@ -1,3 +1,14 @@
* Add `Array#extract!`.
The method removes and returns the elements for which the block returns a true value.
If no block is given, an Enumerator is returned instead.
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
numbers # => [0, 2, 4, 6, 8]
*bogdanvlviv*
* Support not to cache `nil` for `ActiveSupport::Cache#fetch`.
cache.fetch('bar', skip_nil: true) { nil }

View File

@ -3,6 +3,7 @@
require "active_support/core_ext/array/wrap"
require "active_support/core_ext/array/access"
require "active_support/core_ext/array/conversions"
require "active_support/core_ext/array/extract"
require "active_support/core_ext/array/extract_options"
require "active_support/core_ext/array/grouping"
require "active_support/core_ext/array/prepend_and_append"

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
class Array
# Removes and returns the elements for which the block returns a true value.
# If no block is given, an Enumerator is returned instead.
#
# numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
# numbers # => [0, 2, 4, 6, 8]
def extract!(&block)
unless block_given?
to_enum(:extract!) { size }
else
extracted_elements, other_elements = partition(&block)
replace(other_elements)
extracted_elements
end
end
end

View File

@ -0,0 +1,44 @@
# frozen_string_literal: true
require "abstract_unit"
require "active_support/core_ext/array"
class ExtractTest < ActiveSupport::TestCase
def test_extract
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
array_id = numbers.object_id
odd_numbers = numbers.extract!(&:odd?)
assert_equal [1, 3, 5, 7, 9], odd_numbers
assert_equal [0, 2, 4, 6, 8], numbers
assert_equal array_id, numbers.object_id
end
def test_extract_without_block
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
array_id = numbers.object_id
extract_enumerator = numbers.extract!
assert_instance_of Enumerator, extract_enumerator
assert_equal numbers.size, extract_enumerator.size
odd_numbers = extract_enumerator.each(&:odd?)
assert_equal [1, 3, 5, 7, 9], odd_numbers
assert_equal [0, 2, 4, 6, 8], numbers
assert_equal array_id, numbers.object_id
end
def test_extract_on_empty_array
empty_array = []
array_id = empty_array.object_id
new_empty_array = empty_array.extract! {}
assert_equal [], new_empty_array
assert_equal [], empty_array
assert_equal array_id, empty_array.object_id
end
end

View File

@ -2156,6 +2156,19 @@ This method is an alias of `Array#<<`.
NOTE: Defined in `active_support/core_ext/array/prepend_and_append.rb`.
### Extracting
The method `extract!` removes and returns the elements for which the block returns a true value.
If no block is given, an Enumerator is returned instead.
```ruby
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
numbers # => [0, 2, 4, 6, 8]
```
NOTE: Defined in `active_support/core_ext/array/extract.rb`.
### Options Extraction
When the last argument in a method call is a hash, except perhaps for a `&block` argument, Ruby allows you to omit the brackets: