Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One-liner to convert an iterator to an array in Ruby

Tags:

ruby

This has to be a FAQ, but after much web searching, I've failed to find an answer. I'm new to the Ruby programming language, so it's possible that I've misunderstood something fundamental, or that I'm projecting my knowledge of C#, F#, or Haskell onto Ruby.

If I have a method like the following, is there a one-liner to turn it into an array or other mutable data structure?

def foo
  yield 8
  yield 2
  yield 5
end

I know that I can do this:

ary = Array.new
foo { |x| ary << x }

That is, however, not a one-liner. In C#, for example, I can use ToList or ToArray extension methods, or in F# e.g. Seq.toList:

let foo = seq {
    yield 8
    yield 2
    yield 5
}

let arr = foo |> Seq.toList

Is there a similar one-liner in Ruby?

Or did I completely misunderstand the nature of foo?

like image 903
Mark Seemann Avatar asked Feb 05 '21 08:02

Mark Seemann


People also ask

How to use Each Iterator in Ruby?

The each iterator returns all the elements of an array or a hash. Executes code for each element in collection. Here, collection could be an array or a ruby hash. You always associate the each iterator with a block. It returns each value of the array, one by one, to the block. The value is stored in the variable i and then displayed on the screen.

How to loop over arrays in Ruby?

Looping over arrays is another common problem in coding. Again, Ruby does not disappoint in this area. The language has several useful tools designed for this specific problem. The “each” method is built for the specific problem of array iteration. The “each” method is one of our first introductions to higher-level looping in ruby.

How to convert an iterator into an array in C++?

The task is to convert an iterator into an array. This can be performed by iterating each value of the iterator and storing the value into another array . Method: To make an iterator for an array: const it = array[Symbol.iterator](); So first we make an iterator for the “array” named “it”.

What is a collect iterator in Java?

The collect iterator returns an entire collection, regardless of whether it is an array or hash. The collect method need not always be associated with a block. The collect method returns the entire collection, regardless of whether it is an array or a hash. Times Iterator: In this iterator, a loop is implanted with the specific number of time.


1 Answers

There are two independent questions in your question, actually.

The first question is in the title:

One-liner to convert an iterator to an array in Ruby

That is easy: Enumerator, which is what iterators are called in Ruby, mixes in (inherits from) Enumerable. Enumerable has the Enumerable#to_a method that creates an Array from an Enumerable, and thus also from an Enumerator, because Enumerator IS-AN Enumerable.

So, if you have an Enumerator, all you need to do is call to_a, e.g.

some_enum.to_a

However, you don't have an Enumerator. You have a method. So, the real question that you are not asking but that is at the crux of the matter, is: how do I create an Enumerator from a method?

And that's what Object#enum_for does:

enum = enum_for(:foo)
#=> #<Enumerator: ...>

ary = enum.to_a
#=> [8, 2, 5]

Note, however, that in many cases, you do not actually need an Array, since Enumerator inherits from Enumerable just like Array does, and thus responds to many of the same messages.

Also note that by convention, many "iterator" methods in Ruby, e.g. Enumerable#map, #each, etc., will return an Enumerator when they are called without a block:

def foo
  return enum_for(__callee__) { 3 } unless block_given?

  yield 8
  yield 2
  yield 5
end

Then you can simply do:

enum = foo
#=> #<Enumerator: ...>

ary = enum.to_a
#=> [8, 2, 5]
like image 140
Jörg W Mittag Avatar answered Sep 27 '22 22:09

Jörg W Mittag