Namespace
Class
Methods
- compact_blank
- exclude?
- excluding
- in_order_of
- including
- index_by
- index_with
- many?
- maximum
- minimum
- pick
- pluck
- sole
- sum
- without
Instance Public methods
compact_blank()
Returns a new Array without the blank items. Uses Object#blank? for determining if an item is blank.
[1, "", nil, 2, " ", [], {}, false, true].compact_blank
# => [1, 2, true]
Set.new([nil, "", 1, false]).compact_blank
# => [1]
When called on a Hash, returns a new Hash without the blank values.
{ a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank
# => { b: 1, f: true }
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 240
def compact_blank
reject(&:blank?)
end
π See on GitHub
exclude?(object)
The negative of the Enumerable#include?. Returns true if the collection does not include the object.
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 174
def exclude?(object)
!include?(object)
end
π See on GitHub
excluding(*elements)
Returns a copy of the enumerable excluding the specified elements.
["David", "Rafael", "Aaron", "Todd"].excluding "Aaron", "Todd"
# => ["David", "Rafael"]
["David", "Rafael", "Aaron", "Todd"].excluding %w[ Aaron Todd ]
# => ["David", "Rafael"]
{foo: 1, bar: 2, baz: 3}.excluding :bar
# => {foo: 1, baz: 3}
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 188
def excluding(*elements)
elements.flatten!(1)
reject { |element| elements.include?(element) }
end
π See on GitHub
in_order_of(key, series)
Returns a new Array where the order has been set to that provided in the series, based on the key of the objects in the original enumerable.
[ Person.find(5), Person.find(3), Person.find(1) ].in_order_of(:id, [ 1, 5, 3 ])
# => [ Person.find(1), Person.find(5), Person.find(3) ]
If the series include keys that have no corresponding element in the Enumerable, these are ignored. If the Enumerable has additional elements that arenβt named in the series, these are not included in the result.
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 252
def in_order_of(key, series)
group_by(&key).values_at(*series).flatten(1).compact
end
π See on GitHub
including(*elements)
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"]
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 168
def including(*elements)
to_a.including(*elements)
end
π See on GitHub
index_by()
Convert an enumerable to a hash, using the block result as the key and the element as the value.
people.index_by(&:login)
# => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
people.index_by { |person| "#{person.first_name} #{person.last_name}" }
# => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 108
def index_by
if block_given?
result = {}
each { |elem| result[yield(elem)] = elem }
result
else
to_enum(:index_by) { size if respond_to?(:size) }
end
end
π See on GitHub
index_with(default = (no_default = true))
Convert an enumerable to a hash, using the element as the key and the block result as the value.
post = Post.new(title: "hey there", body: "what's up?")
%i( title body ).index_with { |attr_name| post.public_send(attr_name) }
# => { title: "hey there", body: "what's up?" }
If an argument is passed instead of a block, it will be used as the value for all elements:
%i( created_at updated_at ).index_with(Time.now)
# => { created_at: 2020-03-09 22:31:47, updated_at: 2020-03-09 22:31:47 }
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 131
def index_with(default = (no_default = true))
if block_given?
result = {}
each { |elem| result[elem] = yield(elem) }
result
elsif no_default
to_enum(:index_with) { size if respond_to?(:size) }
else
result = {}
each { |elem| result[elem] = default }
result
end
end
π See on GitHub
many?()
Returns true if the enumerable has more than 1 element. Functionally equivalent to enum.to_a.size > 1. Can be called with a block too, much like any?, so people.many? { |p| p.age > 26 } returns true if more than one person is over 26.
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 149
def many?
cnt = 0
if block_given?
any? do |*args|
cnt += 1 if yield(*args)
cnt > 1
end
else
any? { (cnt += 1) > 1 }
end
end
π See on GitHub
maximum(key)
Calculates the maximum from the extracted elements.
payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
payments.maximum(:price) # => 15
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 52
def maximum(key)
map(&key).max
end
π See on GitHub
minimum(key)
Calculates the minimum from the extracted elements.
payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
payments.minimum(:price) # => 5
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 44
def minimum(key)
map(&key).min
end
π See on GitHub
pick(*keys)
Extract the given key from the first element in the enumerable.
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pick(:name)
# => "David"
[{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pick(:id, :name)
# => [1, "David"]
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 217
def pick(*keys)
return if none?
if keys.many?
keys.map { |key| first[key] }
else
first[keys.first]
end
end
π See on GitHub
pluck(*keys)
Extract the given key from each element in the enumerable.
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
# => ["David", "Rafael", "Aaron"]
[{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name)
# => [[1, "David"], [2, "Rafael"]]
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 201
def pluck(*keys)
if keys.many?
map { |element| keys.map { |key| element[key] } }
else
key = keys.first
map { |element| element[key] }
end
end
π See on GitHub
sole()
Returns the sole item in the enumerable. If there are no items, or more than one item, raises Enumerable::SoleItemExpectedError.
["x"].sole # => "x"
Set.new.sole # => Enumerable::SoleItemExpectedError: no item found
{ a: 1, b: 2 }.sole # => Enumerable::SoleItemExpectedError: multiple items found
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 262
def sole
case count
when 1 then return first # rubocop:disable Style/RedundantReturn
when 0 then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "no item found"
when 2.. then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "multiple items found"
end
end
π See on GitHub
sum(identity = nil, &block)
Calculates a sum from the elements.
payments.sum { |p| p.price * p.tax_rate }
payments.sum(&:price)
The latter is a shortcut for:
payments.inject(0) { |sum, p| sum + p.price }
It can also calculate the sum without the use of a block.
[5, 15, 10].sum # => 30
['foo', 'bar'].sum('') # => "foobar"
[[1, 2], [3, 1, 5]].sum([]) # => [1, 2, 3, 1, 5]
The default sum of an empty list is zero. You can override this default:
[].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
π Source code
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 74
def sum(identity = nil, &block)
if identity
_original_sum_with_required_identity(identity, &block)
elsif block_given?
map(&block).sum
else
first = true
reduce(nil) do |sum, value|
if first
first = false
unless value.is_a?(Numeric) || value.respond_to?(:coerce)
ActiveSupport::Deprecation.warn(<<-MSG.squish)
Rails 7.0 has deprecated Enumerable.sum in favor of Ruby's native implementation available since 2.4.
Sum of non-numeric elements requires an initial argument.
MSG
end
value
else
sum + value
end
end || 0
end
end
π See on GitHub