What does `each` method return? [closed] - ruby

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
When I call
#data.each do |d|
some code here
end
what does the each method return? An array of objects? Or more generally, what does do...end block take?

It iterates over the members of the enumerable object. So if #data is an array it will return the elements of the array one at a time as d. Exact behavior depends on the type of object. See the docs
Books.all returns a object, that although it is not an array, behaves like one in this case.

each returns the receiver, in this case #data.
The do ... end is a block.

The each method will run the block (using the method yield) once for each value in data. This is called an iterator. For an array it will iterate over all the values in the array, for a hash it will run once per every pair of (key,value). You can define your own iterator for your own classes.
The return value of each depends on the object it is invoked. When invoked on an array it will return the array.
In your case the method each will execute the block once per each value and send each value as a parameter to the block.
For example-
a = [1,2,3]
a.each do |n|
p n
end
is just the same as
p a[0]
p a[1]
p a[2]

Related

Difference between set and hash? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Seems to me like the only real difference between a hash and a set is that sets don't have keys. Are there any other important differences?
Not all hashes are sets, but a hash can be used as a set.
Sets are collections where the values are...
Unordered
Unique
A hash with only keys matches that, so sets are often implemented as a hash with only keys. The keys are used as the values in the set, so they can be quickly looked up and iterated through.
In Perl it's very common to put a list into a hash to deduplicate it and work with it as a set.
my %set = map { $_ => 1 } #values;
Ruby's Set class is a thin wrapper around a hash. For example, here's Set#add.
# File set.rb, line 312
def add(o)
#hash[o] = true
self
end
If you want to check if something is in the set, just check if its in the hash, an O(1) lookup.
# File set.rb, line 214
def include?(o)
#hash[o]
end
Most set operations, such as intersections and unions are very fast. Intersection just checks if any keys in one hash are in the other, an O(n) operation (leaving aside key collisions). Here's how Ruby does it.
def intersect?(set)
set.is_a?(Set) or raise ArgumentError, "value must be a set"
if size < set.size
any? { |o| set.include?(o) }
else
set.any? { |o| include?(o) }
end
end
Union combines both hashes into one new hash, also an O(n) operation.
def |(enum)
dup.merge(enum)
end

How does find method work in Ruby [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I understood the working of find method i.e. looks for the first occurrence. But I don't understand how find method is implemented at class level. Can somebody explain me the flow of this below written code? Also explain me the relation between find method and yield. How the values are passed between yield call and find call? Also explain what is the use of nil. Thanks.
class Array
def find
each do |value|
return value if yield(value)
end
nil
end
end
[1,3,5,7,9].find {|v| v*v > 30}
First of all; you know how yield works right??
{|v| v*v>30}
every item in the array is passed to this block as param v = every element
Explaination:
return value if yield(value) signifies that the current item of the array is returned from the find method if the block passed return true for the any item of the array.
So, it only returns single item; actually the first item matching the condition; unlike select method that returns every item matching the condition.
2.2.1 :030 > [1,2,3].select{|x| x>1}
=> [2, 3]
Moreover; the each do |value| iterates over the the current/self instance of Array class

Calling #[] on a ruby method [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Create a method that can be called in this manner
some_named_method(string_1, string_2, int_1, int_2)[Integer]
I've just learned that if a method is being called like so some_named_method[80] - that method is a Proc / lambda (? still a little unsure of this any elaboration would be great)
Guidelines are, arguments are optional, in groups of two, based on the tests provided, but the number in brackets will always be present. It is used to create an Array, which is operated on, depending on the params being passed in.. So ->
some_named_method[Integer] # => [0..Integer]
some_named_method('Hey', 'There')[Integer] # some operations based on the string arguments and => [0..Integer]
some_named_method('Hey', 'There', 3, 5)[Integer]
How do you make a lambda have optional arguments in this way?
ANSWER (I think)
When a method is being called in this way, some_named_method(*args)[Integer], one of two things is happening. Either the method returns an array, so #[] is being called on that array, returning whatever object is at the specified index
OR
that method contains a proc / lambda, and whatever is inside the #[some_arguement] is being passed as an argument(s) to that proc / lambda
If I understand the question, you want a method that takes any number of arguments, and returns an object that will create a range of numbers when the [] method is used.
This method takes any number of arguments (using the * splat operator), and then returns a proc, which [] can be used on.
def some_named_function(*args)
proc do |length|
# Do something with the args?
(0..length).to_a
end
end
And then it can be used like this:
some_named_function[3] # => [0, 1, 2, 3]
some_named_function('optional', 'args')[1] # => [0, 1]

How does ruby works with array of arrays [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am facing something i do not fully understand.
I have an array whose elements are arrays.
So I have two nested loops, in the inner loop I fill my inner array
then in the outer loop i fill the outer array with the inner array.
arr=[]
mat=[]
for m in (0..1)
for k in (0..1)
arr[k]=rand.to_s
end
mat[m]=arr
end
At the end my matrix is filled with two array; each array contains the values calculated in the last iteration.
If i want the first element in matrix to contain the first computed array I have to reinitialize the arr object at each loop.
So it seems that assignment is made by reference until the arr object is "cleaned". If I add
mat[m]=arr
arr=[]
all works as expected: mat[0] will contain the array computed in the first loop, and mat[1] will contain the array computed in the second loop.
Is this by design or is it an undesired side effect?
This is happening only if I assign arrays as array elements. If if fill an array with simple string variables in a loop all goes as expected.
I know that it is good programming practice to avoid reusing objects, but this behavior is anyway strange.
Your problem is that your arr variable's contents is being overwritten with each iteration: the arr[k] overwrites whatever is in there already. The arr variable needs to be local to the block instead:
mat = []
2.times do # avoid for... use iterators instead
row = []
2.times do
row << rand.to_s
end
mat << row
end
I like the approach of using hashes instead of multidimensional arrays.
How about this:
def creat­e_matrix x, y, conte­nt = nil, &block
rows = (0...x­).to_a
cols = (0...y­).to_a
indices = rows.­product cols
matrix = {}
indices.ea­ch { |inde­x| matri­x[index] = ( block­_given? ? yield­( index ) : conte­nt ) }
matrix
end
Then do:
matrix = create_matrix( 2, 2 ) { rand.to_s }
You will get a hash, that you can access like this:
matrix[[0, 1]] #note the double brackets
Another way of doing it:
(1..4).map{rand}.each_slice(2).to_a

String interpolation for keys in array? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm supposed to be doing this:
attribute_name = "key_i_want"
scores = []
candidates.each do |candidate|
scores.push candidate.attributes.merge(:{#attribute_name} => {stuff})
end
scores
What I want to happen is that the category name, which in this case has the key "key_i_want", gets added to the hash, and its value will be "stuff". Is there some kind of "interpolate string" function, where I can add hash k-v pairs to an existing hash.
Another thing, what happens in this function is that I have an empty array called "scores", fill it up with the candidate+score hashes, and return the array scores at the end, is there some kind of syntactic sugar or something for this?
Here is the way to merge, as well as the cleaner way to create scores:
scores = candidates.map do |candidate|
candidate.merge({attribute_name => stuff})
end
This uses Hash#merge and Array#map (assuming candidates is an Array).
Ruby has syntactic sugar that wraps method parameters in a Hash for you if you write them in pairs with => between them. So the second line could also be this:
candidate.merge(attribute_name => stuff)
Also, if attribute_name is a String but the rest of the keys in candidate are Symbols, use String#to_sym so that the resulting Hash will have consistent keys:
candidate.merge({attribute_name_string.to_sym => stuff})
Is there some kind of "interpolate string" function, where I can add hash k-v pairs to an existing hash.
No need for interpolation.
Do this:-
merge(attribute_name => stuff)
Another thing, what happens in this function is that I have an empty array called "scores", fill it up with the candidate+score hashes, and return the array scores at the end, is there some kind of syntactic sugar or something for this?
attribute_name = "key_i_want"
candidates.each_with_object([]) do |candidate,scores|
scores.push candidate.attributes.merge(attribute_name => stuff)
end

Resources