123456789_123456789_123456789_123456789_123456789_

Module: Enumerable

Relationships & Source Files
Namespace Children
Exceptions:
Extension / Inclusion / Inheritance Descendants
Included In:
ActionController::MiddlewareStack, ::ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullCookieJar, ActionDispatch::Cookies::CookieJar, ::ActionDispatch::Flash::FlashHash, ::ActionDispatch::Http::Headers, ActionDispatch::Journey::Nodes::Binary, ActionDispatch::Journey::Nodes::Cat, ActionDispatch::Journey::Nodes::Dot, ActionDispatch::Journey::Nodes::Dummy, ActionDispatch::Journey::Nodes::Group, ActionDispatch::Journey::Nodes::Literal, ActionDispatch::Journey::Nodes::Node, ActionDispatch::Journey::Nodes::Or, ActionDispatch::Journey::Nodes::Slash, ActionDispatch::Journey::Nodes::Star, ActionDispatch::Journey::Nodes::Symbol, ActionDispatch::Journey::Nodes::Terminal, ActionDispatch::Journey::Nodes::Unary, ActionDispatch::Journey::Routes, ::ActionDispatch::MiddlewareStack, ActionDispatch::Routing::Mapper::Scope, ActionDispatch::Routing::RouteSet::NamedRouteCollection, ActionView::CollectionRenderer::CollectionIterator, ActionView::CollectionRenderer::MixedCollectionIterator, ActionView::CollectionRenderer::PreloadCollectionIterator, ActionView::CollectionRenderer::SameCollectionIterator, ActionView::PathSet, ::ActiveModel::Errors, ActiveRecord::AssociationRelation, ::ActiveRecord::Associations::CollectionProxy, ActiveRecord::Associations::JoinDependency::JoinAssociation, ActiveRecord::Associations::JoinDependency::JoinBase, ActiveRecord::Associations::JoinDependency::JoinPart, ::ActiveRecord::Batches::BatchEnumerator, ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::StatementPool, ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::StatementPool, ActiveRecord::ConnectionAdapters::SQLite3Adapter::StatementPool, ActiveRecord::ConnectionAdapters::StatementPool, ActiveRecord::DisableJoinsAssociationRelation, ActiveRecord::Fixture, ActiveRecord::FixtureSet::File, ::ActiveRecord::Relation, ::ActiveRecord::Result, ActiveSupport::Callbacks::CallbackChain, ::Mime::Mimes, Rails::Autoloaders, ::Rails::Engine::LazyRouteSet::NamedRouteCollection, ::Rails::Engine::Railties, ::Rails::Initializable::Collection, ::Rails::Paths::Path
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
Defined in: activesupport/lib/active_support/core_ext/enumerable.rb,
activesupport/lib/active_support/core_ext/object/json.rb

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#many?Boolean (readonly)

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.

[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 93

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

Instance Method Details

#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 }
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 184

def compact_blank
  reject(&:blank?)
end

#exclude?(object) ⇒ Boolean

The negative of the Enumerable#include?. Returns true if the collection does not include the object.

[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 118

def exclude?(object)
  !include?(object)
end

#excluding(*elements) Also known as: #without

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}
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 132

def excluding(*elements)
  elements.flatten!(1)
  reject { |element| elements.include?(element) }
end

#in_order_of(key, series, filter: true)

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, unless the filter option is set to false.

[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 197

def in_order_of(key, series, filter: true)
  if filter
    group_by(&key).values_at(*series).flatten(1).compact
  else
    sort_by { |v| series.index(v.public_send(key)) || series.size }.compact
  end
end

#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"]
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 112

def including(*elements)
  to_a.including(*elements)
end

#index_by

Convert an enumerable to a hash, using the block result as the key and the element as the value.

people.index_by(&:)
# => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}

people.index_by { |person| "#{person.first_name} #{person.last_name}" }
# => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 52

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

#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 }
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 75

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

#maximum(key)

Calculates the maximum from the extracted elements.

payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
payments.maximum(:price) # => 15
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 40

def maximum(key)
  map(&key).max
end

#minimum(key)

Calculates the minimum from the extracted elements.

payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
payments.minimum(:price) # => 5
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 32

def minimum(key)
  map(&key).min
end

#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"]
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 161

def pick(*keys)
  return if none?

  if keys.many?
    keys.map { |key| first[key] }
  else
    first[keys.first]
  end
end

#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"]]
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 145

def pluck(*keys)
  if keys.many?
    map { |element| keys.map { |key| element[key] } }
  else
    key = keys.first
    map { |element| element[key] }
  end
end

#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
[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 211

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

#without(*elements)

Alias for #excluding.

[ GitHub ]

  
# File 'activesupport/lib/active_support/core_ext/enumerable.rb', line 136

alias :without :excluding