Вычитание одного массива из другого в Ruby
У меня есть два массива задач - созданные и назначенные.
Я хочу удалить все назначенные задачи из массива созданных задач.
Здесь мой рабочий, но грязный, код:
@assigned_tasks = @user.assigned_tasks
@created_tasks = @user.created_tasks
#Do not show created tasks assigned to self
@created_not_doing_tasks = Array.new
@created_tasks.each do |task|
unless @assigned_tasks.include?(task)
@created_not_doing_tasks << task
end
end
Я уверен, что там лучший способ. Что это?
Спасибо: -)
Ответы
Ответ 1
Вы можете вычесть массивы в Ruby:
[1,2,3,4,5] - [1,3,4] #=> [2,5]
ary - other_ary → new_ary Разница в массиве
Возвращает новый массив, который является копией исходного массива, удаляя любые элементы, которые также отображаются в other_ary. Порядок сохраняется из исходный массив.
Он сравнивает элементы, используя их хэш и eql? методы эффективности.
[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
Если вам нужно set-like behavior, см. класс библиотеки Set.
См. документацию Array.
Ответ 2
Вышеприведенное решение
a - b
удаляет все экземпляры элементов в массиве b
из массива a
.
[ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
В некоторых случаях вы хотите, чтобы результат был [1, 2, 3, 3, 5]
. То есть вы не хотите удалять все дубликаты, но только отдельные элементы.
Вы можете достичь этого
class Array
def delete_elements_in(ary)
ary.each do |x|
if index = index(x)
delete_at(index)
end
end
end
Тест
irb(main):198:0> a = [ 1, 1, 2, 2, 3, 3, 4, 5 ]
=> [1, 1, 2, 2, 3, 3, 4, 5]
irb(main):199:0> b = [ 1, 2, 4 ]
=> [1, 2, 4]
irb(main):200:0> a.delete_elements_in(b)
=> [1, 2, 4]
irb(main):201:0> a
=> [1, 2, 3, 3, 5]
Код работает даже тогда, когда два массива не отсортированы. В этом примере массивы отсортированы, но это не требуется.