Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a method that accepts blocks and can return truthy or falsey values

So, I am back with another question! I have learned how to accept arguments with blocks but I need now to place a block in my method (I think).

Here is what I have to do, it's a generalized reduce method with the following tests going through it:

describe 'my own reduce' do
  it "returns a running total when not given a starting point" do
    source_array = [1,2,3]
    expect(reduce(source_array){|memo, n| memo + n}).to eq(6)
  end

  it "returns a running total when given a starting point" do
    source_array = [1,2,3]
    starting_point = 100
    expect(reduce(source_array, starting_point){|memo, n| memo + n}).to eq(106)
  end

  it "returns true when all values are truthy" do
    source_array = [1, 2, true, "razmatazz"]
    expect(reduce(source_array){|memo, n| memo && n}).to be_truthy
  end

  it "returns false when any value is false" do
    source_array = [1, 2, true, "razmatazz", false]
    expect(reduce(source_array){|memo, n| memo && n}).to be_falsy
  end

  it "returns true when a truthy value is present" do
    source_array = [ false, nil, nil, nil, true]
    expect(reduce(source_array){|memo, n| memo || n}).to eq(true)
  end

  it "returns false when no truthy value is present" do
    source_array = [ false, nil, nil, nil]
    expect(reduce(source_array){|memo, n| memo && n}).to eq(false)
  end
end

Here is my code:

def reduce(element1, starting_point = 0, &block)
  element1.reduce(starting_point, &block)
end

Which passes 4 out of the 6 tests. But the last part requires checking the values in the source_array and if any are truthy return true or if any are falsey, return false. I tried putting in the follow block along with the reduce method:

def reduce(element1, starting_point = 0, &block)
  element1.reduce(starting_point, &block){ |x, y| if x || y = true; p true; else p false; end}
end

If you look at the tests, you can see it will pass one array with 'true' and one with 'false' and I need it to work for all the 6 tests.

Please, any explanation has been helping me greatly.

like image 258
Roderick Cardenas Avatar asked Oct 16 '25 05:10

Roderick Cardenas


2 Answers

  1. If your job is to write your own reduce, don't use Enumerable#reduce inside. You can use Enumerable#each or for/while loop
  2. You can pass a block to another method just as you do it with method(arg1, arg2, &block).
  3. You can call your block with #call, e.g. block.call(arg1, arg2)
like image 113
mrzasa Avatar answered Oct 17 '25 19:10

mrzasa


You cannot specify a default value for starting_point which will work for every use case, since you want to use numbers & booleans.

If you don't specify a starting_point, reduce will simply use the first element as starting_point:

def reduce(elements, starting_point = nil, &block)
  if starting_point.nil?
    elements.reduce(&block)
  else
    elements.reduce(starting_point, &block)
  end
end
like image 45
Eric Duminil Avatar answered Oct 17 '25 20:10

Eric Duminil



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!