Joseph Cake
Joseph Cake

Reputation: 9

Returning boolean instead of value, re-creating .select method

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

Answers (2)

kiddorails
kiddorails

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

Marek Lipka
Marek Lipka

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

Related Questions