Удаление элементов от массива Ruby

Скажем, я пытаюсь удалить элементы из массива a = [1,1,1,2,2,3]. Если я выполняю следующее:

b = a - [1,3]

Затем я доберусь:

b = [2,2]

Однако я хочу, чтобы результат был

b = [1,1,2,2]

т.е. Я только удаляю один экземпляр каждого элемента в вычтенном векторе не все случаи. Существует ли простой путь в Ruby, чтобы сделать это?

60
задан 29 June 2014 в 03:33

1 ответ

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

arr = [1,1,1,2,2,3,1]
removals = [1,3,1]

h = removals.group_by(&:itself).transform_values(&:size)
  #=> {1=>2, 3=>1} 
arr.each_with_object([]) { |n,a|
  h.key?(n) && h[n] > 0 ? (h[n] -= 1) : a << n }
  #=> [1, 2, 2, 1]

arr
  #=> [1, 1, 1, 2, 2, 3, 1] 

Для видоизменения arr запись:

h = removals.group_by(&:itself).transform_values(&:count)
arr.replace(arr.each_with_object([]) { |n,a|
  h.key?(n) && h[n] > 0 ? (h[n] -= 1) : a << n })
  #=> [1, 2, 2, 1]

arr
  #=> [1, 2, 2, 1]

Это использует 21 <глоток> Св. метод века Hash#transform_values (новый в МРТ v2.4), но можно было вместо этого записать:

h = Hash[removals.group_by(&:itself).map { |k,v| [k,v.size] }]

или

h = removals.each_with_object(Hash.new(0)) { | n,h| h[n] += 1 }
0
ответ дан 1 November 2019 в 10:42

Другие вопросы по тегам:

Похожие вопросы: