Пропустить итерацию в Enumerable # collect
(1..4).collect do |x|
next if x == 3
x + 1
end # => [2, 3, nil, 5]
# desired => [2, 3, 5]
Если условие для next
выполнено, collect
помещает nil
в массив, тогда как то, что я пытаюсь сделать, не помещает элемент в возвращенный массив, если условие выполнено. Возможно ли это без вызова delete_if { |x| x == nil }
в возвращаемом массиве?
(Использование Ruby 1.8.7, мой фрагмент кода сильно абстрагирован)
Ответы
Ответ 1
Существует метод Enumerable#reject
, который служит только для этой цели:
(1..4).reject{|x| x == 3}.collect{|x| x + 1}
Практика прямого использования вывода одного метода в качестве входа другого называется цепью метода и очень распространена в Ruby.
BTW, map
(или collect
) используется для прямого отображения ввода, перечислимого на выходной. Если вам нужно вывести различное количество элементов, возможно, вам нужен другой метод Enumerable
.
Изменить: Если вас беспокоит тот факт, что некоторые из элементов повторяются дважды, вы можете использовать менее элегантное решение на основе inject
(или его аналогичный метод с именем each_with_object
):
(1..4).each_with_object([]){|x,a| a << x + 1 unless x == 3}
Ответ 2
Я бы просто вызвал .compact
в результирующем массиве, который удаляет все экземпляры nil в массиве. Если вы хотите изменить существующий массив (без причины), используйте .compact!
:
(1..4).collect do |x|
next if x == 3
x
end.compact!
Ответ 3
просто предложение, почему бы вам не сделать так:
result = []
(1..4).each do |x|
next if x == 3
result << x
end
result # => [1, 2, 4]
таким образом вы сохранили другую итерацию, чтобы удалить элементы nil из массива. надеюсь, что это помогает =)
Ответ 4
я предлагаю использовать:
(1..4).to_a.delete_if {|x| x == 3}
вместо команды collect + next.
Ответ 5
Вы можете вывести принятие решения в вспомогательный метод и использовать его через Enumerable#reduce
:
def potentially_keep(list, i)
if i === 3
list
else
list.push i
end
end
# => :potentially_keep
(1..4).reduce([]) { |memo, i| potentially_keep(memo, i) }
# => [1, 2, 4]