Reputation: 9
I'm trying to re-create the select
method using a while
loop and yield
. Below is my code:
def my_select(collection)
count = 0
newColl = []
while collection.length > count
if (collection[count] % 2 == 0)
newColl.push(yield (collection[count]))
end
count += 1
end
newColl
end
When I run the following:
arr = [1, 2, 3, 4, 5]
my_select(arr) do |num|
num.even?
end
I want this result:
[2, 4]
but I get this:
[true, true]
I get a boolean return instead of the actual value.
Upvotes: 0
Views: 153
Reputation: 13014
Change it to:
def my_select(collection)
count = 0
newColl = []
while collection.length > count
if (collection[count] % 2 == 0)
result = yield collection[count] # yield first
newColl.push(collection[count]) if result # then push to newColl if required
end
count += 1
end
newColl
end
arr = [1, 2, 3, 4, 5]
my_select(arr) {|num| num.even? }
#=> [2,4]
Though, your newColl
collection is pretty much useless here.
Edit:
Since you mentioned about re-creating select
, this might be an alternative:
def my_select(collection)
# it iterates on the collection and filters the item for which the block return true, at the end, I compact the collection to remove nils
collection.map do |item|
item if yield(item)
end.compact
end
# or
def my_select(collection)
# start with a blank array
coll = []
# iterate on collection
collection.each do |item|
# insert all those items for which the block returns true by yield(item)
coll << item if yield(item)
end
# return the array
coll
end
arr = [1, 2, 3, 4, 5]
my_select(arr) {|num| num.even? }
#=> [2, 4]
Upvotes: 1
Reputation: 51171
It's because you push the result of yield
(which can, but doesn't have to be boolean) instead of actual collection element. You should more add element based on what yield
returns, like this:
element = collection[count]
newColl.push(element) if yield(element)
BTW I don't really get why you're checking the number parity inside of my_select
method? It makes no sense.
Upvotes: 2