2015-05-08 4 views
3

Я только начинаю с Ruby, я довольно в курсе своего курса в блоке, но теперь я застрял в упражнении, касающемся урожая и блоков (которые я считаю самыми трудными концепция, чтобы понять до сих пор, когда дело доходит до обучения рубину).Ruby Blocks (Доходность)

Вот необходимые данные в виде простого форматированного текста:

  • определить new_map метод
  • Он должен принять массив в качестве аргумента и возвращает новый массив измененную в соответствии с инструкциями, принятыми в качестве блока ,
  • Вы не можете использовать карту .map или .map! Методы
  • Однако, Вы можете использовать каждый в рамках метода
  • Вы хотите сохранить возвращаемое значение из каждого блока вызова в новом массиве
  • Он должен отобразить любой объект

Вот RSpecs, которые должны быть выполнены:

describe "new_map" do 
    it "should not call map or map!" do 
    a = [1, 2, 3] 
    a.stub(:map) { '' } 
    a.stub(:map!) { '' } 

    expect(new_map(a) { |i| i + 1 }).to eq([2, 3, 4]) 
    end 

    it "should map any object" do 
    a = [1, "two", :three] 
    expect(new_map(a) { |i| i.class }).to eq([Fixnum, String, Symbol]) 
    end 
end 

Вот оригинальный метод Защиту они дали мне начать с:

def new_map(array) 
    new_array = [] 
    array.each do |item| 
    # invoke the block, and add its return value to the new array 
    end 
end 

Тогда вот мой текущий код (Обновлено):

def new_map(a) 
    new_array = [] 
    a.each do |item| 
    # invoke the block, and add its return value to the new array. 
    yield(item, new_array) 
    end 
end 

a = [2, 3, 4] 

new_map(a) do |i, e| 
    e << i 
end 

Наконец, когда я представляю текущий код, который я только что перечислил, я получаю следующие ошибки (Обновлено):

new_map не следует называть карту или карту! (НЕПОЛНЫЙ)

expected: [2, 3, 4] 
    got: [1, 2, 3] 

(compared using ==) 
exercise_spec.rb:9:in `block (2 levels) in <top (required)>' 

new_map следует сопоставить любой объект (неполный)

expected: [Fixnum, String, Symbol] 
    got: [1, "two", :three] 

(compared using ==) 

exercise_spec.rb:14:in `block (2 levels) in <top (required)>' 
+0

Как и говорится - при вызове 'new_map (a)', 'a' не определено. Перед вызовом new_map установите его на начальное значение, например массив чисел. –

+0

@ChrisHeald не работает, я устанавливаю 'a = [1, 2, 3, 4]' между определением метода и вызовом метода. Программа выполняется сейчас, но я получаю 'ожидаемый: [2, 3, 4 ] получил: [] ' –

+0

Кроме того, возможно, более подробно рассмотрите текст комментария. Шаг 1) Выполните блок. Шаг 2) Добавьте его значение в массив. – user12341234

ответ

1

Что вы не понимаете, так это то, что доходность может вернуть значение. Последний выполненный оператор в блоке - это возвращаемое значение.

Таким образом, вы можете получить результаты от каждого вызова доходности и добавить его в результирующий массив.

Затем получите результирующий массив в качестве возвращаемого значения из вашего метода new_map.

def new_map(a) 
    new_array = [] 
    a.each do |item| 
    # invoke the block, and add its return value to the new array. 
    new_array << yield(item) 
    end 
    new_array 
end 
+0

Большое спасибо @SteveTurczyn, который отлично работал, я ценю это. –

0

new_array создаются в определении new_map, которая представляет собой другую "лексическая область" чем блок, который вы пишете, когда звоните new_map. В принципе, код в методе new_map может видеть new_array, но код в вашем блоке не может. Один из способов устранить эту проблему можно, посмотрев на методы Enumerableinject или each_with_object, которые могут работать вместо each в вашем методе new_map.

1

Попробуйте это:

def new_map(a) 
    new_array = [] 
    a.each do |item| 
    # # invoke the block, and add its return value to the new array. 
    puts yield(item) # just experimenting 
    end 
end 

new_map(a) { |i| i + 1 } 

yield Эта штуковина просто принимает каждый элемент из массива, и запускает его через блок. Этот экспериментальный код просто печатает результаты; они должны собираться в массиве. Не сложно:

def new_map(a) 
    new_array = [] 
    a.each do |item| 
    new_array = [] 
    # invoke the block, and add its return value to the new array. 
    new_array << yield(item) 
    end 
end 

Это не пройдет все испытания, но последний шаг должен быть выполнимым.

Смежные вопросы