Ruby: удалить все экземпляры повторяющегося значения внутри массива - PullRequest
0 голосов
/ 11 мая 2018

У меня есть один массив, и я хочу удалить ВСЕ экземпляры повторяющегося значения внутри этого массива.

arr = [1, 1, 2, 3, 4, 4, 5]

Я хочу ожидаемый результат:

=> [2, 3, 5]

Как лучше всего это сделать?

Ответы [ 4 ]

0 голосов
/ 13 мая 2018

enter image description here

+ 1 для: arr.uniq.select {| n |arr.count (n) == 1} кажется более читабельным и чистым

@ cary-swoveland Array # разница, похоже, имеет некоторые проблемы с производительностью.

0 голосов
/ 11 мая 2018
p arr.group_by(&:itself).reject{|k,v|v.count>1}.keys

Выход

[2, 3, 5]
0 голосов
/ 11 мая 2018

Вот три способа сделать это (ответ Раджагопалана - другой).

arr = [1, 1, 2, 3, 4, 4, 5]

Использовать счетный хеш

arr.each_with_object(Hash.new(0)) { |n,h| h[n] += 1 }.select { |_,v| v == 1 }.keys
  # => [2, 3, 5]

Используйте Array # count

arr.uniq.select { |n| arr.count(n) == 1 }
  #=> [2, 3, 5]

Это может показаться относительно неэффективным, учитывая, что arr необходимо пройти для каждого элемента arr.uniq.Однако, если arr.uniq не слишком велико, оно может быть быстрее, чем использование счетного хэша или (как это сделал Раджагопалан) Enumerable # group_by .

Использовать Массив # разница

Array#difference - это метод, который я предложил добавить в ядро ​​Ruby.

class Array
  def difference(other)
    h = other.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
    reject { |e| h[e] > 0 && h[e] -= 1 }
  end
end

Если бы мы использовали этот метод, мы могли бынапишите следующее.

arr - arr.difference(arr.uniq)
  #=> [2, 3, 5] 
0 голосов
/ 11 мая 2018

https://apidock.com/ruby/Array/uniq

arr = [1, 1, 2, 3, 4, 4, 5]
arr.uniq 

возвращает

[1, 2, 3, 4, 5]
...