0

I'm trying to return odd elements using this method

def odd_elements(array)
  retArr = Array.new
  array.each_with_index do |item, index|
    if block_given?
      yield(item)
    else
      retArr << item
    end if index % 2 != 0
  end

  return retArr
end

so that I could pass both these tests

it "should yield odd elements" do
  res = odd_elements([1,2,3,4,5,6])
  res.should be_an_instance_of Array
  res.should have(3).items
  res.should include(2)
  res.should include(4)
  res.should include(6)
end

it "should yield" do
  res = odd_elements([1,2,3,4,5,6]) {|x| x**2 }
  res.should be_an_instance_of Array
  res.should have(3).items
  res[0].should == 4
  res[1].should == 16
  res[2].should == 36
end

but I'm failing in the second one. It seems I don't understand how to yield and I didn't manage to get it right in two hours trying so many different things. Could you please explain me why it does not work?

4

2 回答 2

1

yield返回一个您似乎想要添加到的值retArr

def odd_elements(array)
  retArr = []
  array.each_with_index do |item, index|
    retArr << (block_given? ? yield(item) : item) if index % 2 != 0
  end
  retArr
end

我个人更喜欢Enumerator(如果您使用的是 Ruby 1.9.3+),速度稍慢但可以说更具可读性和灵活性:

def odd_elements(array)
  Enumerator.new do |e| 
    odd = false
    array.each do |x| 
      e << x if odd
      odd = ! odd
    end
  end
end

a = [1,2,3,4]

odd_elements(a).to_a #=> [2, 4]
odd_elements(a).map { |x| x * 2 } #=> [4, 8] 
于 2013-09-30T17:02:33.330 回答
1
odd_elements([1,2,3,4,5,6]){|x|p x**2 } #note the p
#=> 4
#=> 16
#=> 36

它产生的很好,但你永远不会将结果存储在数组中。

odd_elements([1,2,3,4,5,6]).map {|x| x**2 }

会将结果保存在数组中。

于 2013-09-30T16:01:07.710 回答