0

I have this code

arr = [1, 2, 3].select do |n|
  n + 2
  puts n
end

The output is

1
2
3

and the return value is

[]

Then I have this code

arr = [1, 2, 3].select do |n|  
  n + 2
end

and the return value is

[1, 2, 3]

So I know that Array#select invokes the block passing in successive elements from self, returning an array containing those elements for which the block returns a true value. How does it behave in those code examples so I could understand why it returns these values.

2 Answers 2

5

Array#select creates a new array using the elements of your array that return truthy from the block.

In your first case, the last line of your block is a puts statement which always returns nil. Hence the [].

In your second case, the last line of your block is always a number, so always truthy. Hence the output equals the input.

Sign up to request clarification or add additional context in comments.

5 Comments

And why in the first code example it doesn't return [nil, nil, nil]?
It makes a subset of your Array using only the elements that return truthy. The elements that return nil, don't get added at all.
Actually I know why ...because everything in ruby is truthy except false and nil?
Yes. select is only going to give you the same element you started with or nothing. If you want to change the elements, you might be more interested in Array#map. For example, [1,2,3].map{ |n| n+2} would be [3,4,5].
I know about map. I am learning Ruby at online bootcamp and in the tests they require us to understand how select, map and each really work behind the scenes. Thanks for your answer!
1

Array#select returns a new array with all the elements that returned true from the block. It does this by iterating over each element, passing it to the block, running the block if the block returns true it puts the element in the new array if not it will skip it and once done it will return a new array.

With that said there are a few other things we should know first before delving into the problem you're having.

1) In Ruby there's a concept called Truthiness. That means that every element except for nil and false evaluates to true. Take for example if I ran this conditional

if 'happy puppy'
  puts "I'm the happiest puppy"
end

You'd see that I'm the happiest puppy is output. That's because the string, not being false or nil, will evaluate to true. Conversely if ran this code

if nil
  puts "Truthiness means all things evaluate to true except nil and false"
end

In this example, the conditional wouldn't output the string because nil doesn't evaluate to true.

2) Pay careful attention to what a method outputs and returns. In the case of Kernel#Puts it outputs n and returns nil. When the block being passed to Array#select is invoked it runs each line of code in the block including puts. That's why we see each number output. Then, this is the important part, it returns nil. Now remember the rules of Truthiness? Because this is the last line of code in the block it's the implicit return of the entire block. That means the block will return nil which evaluates to false.

3) Now on to Array#select, it works by iterating over each element in an array and invoking the block on it. Based on the return value of the block it'll decide whether or not the element belongs in the return array. In your first example, puts is used on the last line and returns nil which means that the block will always evaluate to false. That's why it outputs the element but then returns an empty array. In the second example, the last line in the block is n+2 which will evaluate to an integer. This is where truthiness comes in to play, an integer (or anything besides false or nil) will always evaluate to true. This means the block always returns true. That's why all the elements are returned in the array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.