Фильтр для исключения элементов из массива

Попытка фильтровать некоторые записи из массива. Это не гарантирует, что они находятся в главном массиве, поэтому я тестирую итерацию.

total = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
hide = ['charlie', 'echo']

pick = []
for i in total
  if !hide.include?(i)
    puts i
    pick.push(i)
  end
end
puts pick

Это не работает. Есть ли лучший способ обеспечения такого фильтра?

Ответ 1

Ruby позволяет использовать общедоступные методы экземпляра для двух массивов, чтобы получить их пересекающиеся или исключительные элементы:

a1 = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
a2  = ['charlie', 'echo']
puts a1 - a2
=>  ['alpha', 'bravo', 'delta']

puts a1 & a2
=>  ['charlie', 'echo']

Для получения дополнительной информации проверьте Rubydoc Array. Вполне вероятно, что вы найдете именно то, что вам нужно там.

Ответ 2

Ваш код работает для меня. Что касается "лучшего способа", вы можете использовать Array#reject:

total = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
hide = ['charlie', 'echo']

pick = total.reject do |i|
  hide.include?(i)
end
puts pick

Не только это более идиоматично, но петли Ruby for i in collection реализованы в терминах collection.each { |i| }. Метод с блоком почти всегда является лучшей альтернативой.

Ответ 3

Как насчет .select/reject? Или мутантная версия .select!/reject! ?

Вот документы.

Использование:

[0, 1, 2, 3].select { |x| x > 1 }
# output: [2, 3]

Или в вашем случае:

execluded = [0, 1]
[0, 1, 2, 3].reject { |x| execluded.include?(x) }
# output: [2, 3]