Returns the result of applying a reducer to an initial value and the first element of the Enumerable
. It then takes the result and applies the function to it and the second element of the collection, and so on. The return value is the result returned by the final call to the function.
You can think of
[ a, b, c, d ].inject(i) { |r, v| fn(r, v) }
as being
fn(fn(fn(fn(i, a), b), c), d)
In a way the inject
function injects the function between the elements of the enumerable.
inject
is aliased as reduce
. You use it when you want to reduce a collection to a single value.
The Calling Sequences
Let’s start with the most verbose:
enum.inject(initial_value) do |result, next_value| # do something with +result+ and +next_value+ # the value returned by the block becomes the # value passed in to the next iteration # as +result+ end
For example:
product = [ 2, 3, 4 ].inject(1) do |result, next_value| result * next_value end product #=> 24
When this runs, the block is first called with 1
(the initial value) and 2
(the first element of the array). The block returns 1*2
, so on the next iteration the block is called with 2
(the previous result) and 3
. The block returns 6
, and is called one last time with 6
and 4
. The result of the block, 24
becomes the value returned by inject
. This code returns the product of the elements in the enumerable.
First Shortcut: Default Initial value
In the case of the previous example, the initial value, 1
, wasn’t really necessary: the calculation of the product of a list of numbers is self-contained.
In these circumstances, you can omit the initial_value
parameter. inject
will then initially call the block with the first element of the collection as the result
parameter and the second element as the next_value
.
[ 2, 3, 4 ].inject do |result, next_value| result * next_value end
This shortcut is convenient, but can only be used when the block produces a result which can be passed back to it as a first parameter.
Here’s an example where that’s not the case: it returns a hash where the keys are words and the values are the number of occurrences of that word in the enumerable.
freqs = File.read("README.md") .scan(/\w{2,}/) .reduce(Hash.new(0)) do |counts, word| counts[word] += 1 counts end freqs #=> {"Actions"=>4, "Status"=>5, "MinGW"=>3, "https"=>27, "github"=>10, "com"=>15, ...
Note that the last line of the block is just the word counts
. This ensures the return value of the block is the result that’s being calculated.
Second Shortcut: a Reducer function
A reducer function is a function that takes a partial result and the next value, returning the next partial result. The block that is given to inject
is a reducer.
You can also write a reducer as a function and pass the name of that function (as a symbol) to inject
. However, for this to work, the function
Must be defined on the type of the result value
Must accept a single parameter, the next value in the collection, and
Must return an updated result which will also implement the function.
Here’s an example that adds elements to a string. The two calls invoke the functions String#concat
and String#+
on the result so far, passing it the next value.
s = [ "cat", " ", "dog" ].inject("", :concat) s #=> "cat dog" s = [ "cat", " ", "dog" ].inject("The result is:", :+) s #=> "The result is: cat dog"
Here’s a more complex example when the result object maintains state of a different type to the enumerable elements.
class Turtle def initialize @x = @y = 0 end def move(dir) case dir when "n" then @y += 1 when "s" then @y -= 1 when "e" then @x += 1 when "w" then @x -= 1 end self end end position = "nnneesw".chars.reduce(Turtle.new, :move) position #=>> #<Turtle:0x00000001052f4698 @y=2, @x=1>
Third Shortcut: Reducer With no Initial Value
If your reducer returns a value that it can accept as a parameter, then you don’t have to pass in an initial value. Here :*
is the name of the times function:
product = [ 2, 3, 4 ].inject(:*) product # => 24
String
concatenation again:
s = [ "cat", " ", "dog" ].inject(:+) s #=> "cat dog"
And an example that converts a hash to an array of two-element subarrays.
nested = {foo: 0, bar: 1}.inject([], :push) nested # => [[:foo, 0], [:bar, 1]]
Returns the first element or elements.
With no argument, returns the first element, or nil
if there is none:
(1..4).first # => 1 %w[a b c].first # => "a" {foo: 1, bar: 1, baz: 2}.first # => [:foo, 1] [].first # => nil
With integer argument n
, returns an array containing the first n
elements that exist:
(1..4).first(2) # => [1, 2] %w[a b c d].first(3) # => ["a", "b", "c"] %w[a b c d].first(50) # => ["a", "b", "c", "d"] {foo: 1, bar: 1, baz: 2}.first(2) # => [[:foo, 1], [:bar, 1]] [].first(2) # => []
Returns the element with the minimum element according to a given criterion. The ordering of equal elements is indeterminate and may be unstable.
With no argument and no block, returns the minimum element, using the elements’ own method <=> for comparison:
(1..4).min # => 1 (-4..-1).min # => -4 %w[d c b a].min # => "a" {foo: 0, bar: 1, baz: 2}.min # => [:bar, 1] [].min # => nil
With positive integer argument n
given, and no block, returns an array containing the first n
minimum elements that exist:
(1..4).min(2) # => [1, 2] (-4..-1).min(2) # => [-4, -3] %w[d c b a].min(2) # => ["a", "b"] {foo: 0, bar: 1, baz: 2}.min(2) # => [[:bar, 1], [:baz, 2]] [].min(2) # => []
With a block given, the block determines the minimum elements. The block is called with two elements a
and b
, and must return:
A negative integer if a < b
.
Zero if a == b
.
A positive integer if a > b
.
With a block given and no argument, returns the minimum element as determined by the block:
%w[xxx x xxxx xx].min {|a, b| a.size <=> b.size } # => "x" h = {foo: 0, bar: 1, baz: 2} h.min {|pair1, pair2| pair1[1] <=> pair2[1] } # => [:foo, 0] [].min {|a, b| a <=> b } # => nil
With a block given and positive integer argument n
given, returns an array containing the first n
minimum elements that exist, as determined by the block.
%w[xxx x xxxx xx].min(2) {|a, b| a.size <=> b.size } # => ["x", "xx"] h = {foo: 0, bar: 1, baz: 2} h.min(2) {|pair1, pair2| pair1[1] <=> pair2[1] } # => [[:foo, 0], [:bar, 1]] [].min(2) {|a, b| a <=> b } # => []
Returns a 2-element array containing the minimum and maximum elements according to a given criterion. The ordering of equal elements is indeterminate and may be unstable.
With no argument and no block, returns the minimum and maximum elements, using the elements’ own method <=> for comparison:
(1..4).minmax # => [1, 4] (-4..-1).minmax # => [-4, -1] %w[d c b a].minmax # => ["a", "d"] {foo: 0, bar: 1, baz: 2}.minmax # => [[:bar, 1], [:foo, 0]] [].minmax # => [nil, nil]
With a block given, returns the minimum and maximum elements as determined by the block:
%w[xxx x xxxx xx].minmax {|a, b| a.size <=> b.size } # => ["x", "xxxx"] h = {foo: 0, bar: 1, baz: 2} h.minmax {|pair1, pair2| pair1[1] <=> pair2[1] } # => [[:foo, 0], [:baz, 2]] [].minmax {|a, b| a <=> b } # => [nil, nil]
Returns whether for any element object == element
:
(1..4).include?(2) # => true (1..4).include?(5) # => false (1..4).include?('2') # => false %w[a b c d].include?('b') # => true %w[a b c d].include?('2') # => false {foo: 0, bar: 1, baz: 2}.include?(:foo) # => true {foo: 0, bar: 1, baz: 2}.include?('foo') # => false {foo: 0, bar: 1, baz: 2}.include?(0) # => false
Returns an enumerator object generated from this enumerator and given enumerables.
e = (1..3).chain([4, 5]) e.to_a #=> [1, 2, 3, 4, 5]
Returns a list of the supported category symbols.
Enables the coverage measurement. See the documentation of Coverage
class in detail. This is equivalent to Coverage.setup
and Coverage.resume
.
Returns the state of the coverage measurement.
Returns the short user name of the currently logged in user. Unfortunately, it is often rather easy to fool ::getlogin
.
Avoid ::getlogin
for security-related purposes.
If ::getlogin
fails, try ::getpwuid
.
See the unix manpage for getpwuid(3)
for more detail.
e.g.
Etc.getlogin -> 'guest'
Returns system temporary directory; typically “/tmp”.
Returns a Digest
subclass by name
require 'openssl' OpenSSL::Digest("MD5") # => OpenSSL::Digest::MD5 Digest("Foo") # => NameError: wrong constant name Foo
Returns a Digest
subclass by name
require 'openssl' OpenSSL::Digest("MD5") # => OpenSSL::Digest::MD5 Digest("Foo") # => NameError: wrong constant name Foo
Decompresses string
. Raises a Zlib::NeedDict
exception if a preset dictionary is needed for decompression.
This method is almost equivalent to the following code:
def inflate(string) zstream = Zlib::Inflate.new buf = zstream.inflate(string) zstream.finish zstream.close buf end
See also Zlib.deflate
Return true
if the named file exists.
file_name can be an IO
object.
“file exists” means that stat() or fstat() system call is successful.
Returns true
if the named file is writable by the effective user and group id of this process. See eaccess(3).
Note that some OS-level security features may cause this to return true even though the file is not writable by the effective user/group.
Returns true
if filepath
points to a symbolic link, false
otherwise:
symlink = File.symlink('t.txt', 'symlink') File.symlink?('symlink') # => true File.symlink?('t.txt') # => false
Returns true
if the named file has the sticky bit set.
file_name can be an IO
object.
Initiates garbage collection, even if manually disabled.
The full_mark
keyword argument determines whether or not to perform a major garbage collection cycle. When set to true
, a major garbage collection cycle is run, meaning all objects are marked. When set to false
, a minor garbage collection cycle is run, meaning only young objects are marked.
The immediate_mark
keyword argument determines whether or not to perform incremental marking. When set to true
, marking is completed during the call to this method. When set to false
, marking is performed in steps that are interleaved with future Ruby code execution, so marking might not be completed during this method call. Note that if full_mark
is false
, then marking will always be immediate, regardless of the value of immediate_mark
.
The immediate_sweep
keyword argument determines whether or not to defer sweeping (using lazy sweep). When set to false
, sweeping is performed in steps that are interleaved with future Ruby code execution, so sweeping might not be completed during this method call. When set to true
, sweeping is completed during the call to this method.
Note: These keyword arguments are implementation and version-dependent. They are not guaranteed to be future-compatible and may be ignored if the underlying implementation does not support them.
Returns a Hash
containing information about the GC.
The contents of the hash are implementation-specific and may change in the future without notice.
The hash includes internal statistics about GC such as:
The total number of garbage collections run since application start (count includes both minor and major garbage collections)
The total time spent in garbage collections (in milliseconds)
The total number of :heap_eden_pages
+ :heap_tomb_pages
The number of pages that can fit into the buffer that holds references to all pages
The total number of pages the application could allocate without additional GC
The total number of slots in all :heap_allocated_pages
The total number of slots which contain live objects
The total number of slots which do not contain live objects
The total number of slots with pending finalizers to be run
The total number of objects marked in the last GC
The total number of pages which contain at least one live slot
The total number of pages which do not contain any live slots
The cumulative number of pages allocated since application start
The cumulative number of pages freed since application start
The cumulative number of objects allocated since application start
The cumulative number of objects freed since application start
Amount of memory allocated on the heap for objects. Decreased by any GC
When :malloc_increase_bytes
crosses this limit, GC is triggered
The total number of minor garbage collections run since process start
The total number of major garbage collections run since process start
The total number of compactions run since process start
The total number of times the read barrier was triggered during compaction
The total number of objects compaction has moved
The total number of objects without write barriers
When :remembered_wb_unprotected_objects
crosses this limit, major GC is triggered
Number of live, old objects which have survived at least 3 garbage collections
When :old_objects
crosses this limit, major GC is triggered
Amount of memory allocated on the heap for objects. Decreased by major GC
When :oldmalloc_increase_bytes
crosses this limit, major GC is triggered
If the optional argument, hash, is given, it is overwritten and returned. This is intended to avoid the probe effect.
This method is only expected to work on CRuby.
The path where gem executables are to be installed.
The path were rubygems plugins are to be installed.
Get the default RubyGems API host. This is normally https://rubygems.org
.