Допустим, у меня есть

array1=[1,2,1,1,5]

Как я могу найти любые дубликаты и поместить их в другой массив, например, array2, но только если их больше 3?

Моя цель

array2=[1,1,1]
-2
Aleksandar Jeftic 7 Сен 2017 в 19:09

3 ответа

Лучший ответ

Используя select, вы можете получить элементы вашего array1, которые присутствуют 3 или более раз, как я вижу в вашем ожидаемом выходе:

array1 = [1,2,1,1,5]
array2 = array1.select { |e| array1.count(e) >= 3 }
p array2
# [1, 1, 1]

Если нет элементов, повторяемых 3 или более раз, массив2 будет пустым.

2
Sebastian Palma 7 Сен 2017 в 16:16

Это сохраняет порядок и имеет O (n) временную сложность, n является размером массива.

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

Шаги следующие.

g = array1.each_with_object(Hash.new(0)) { |n,h| h[n]+= 1 }
  #=> {3=>4, 2=>3, 1=>4, 5=>1}
h = g.select { |_,cnt| cnt <= 3 }
  #=> {2=>3, 5=>1}
a = h.keys
  #=> [2, 5]
array1 - a
  #=> [3, 1, 3, 1, 1, 1, 3, 3]

Hash :: new со значением по умолчанию (здесь ноль) часто называют подсчитывающим хешем . Если h = Hash.new(0) и h не имеют ключа k, тогда h[k] возвращает значение по умолчанию 0.

Когда Руби встречает выражение h[k] += 1, первое, что она делает, это расширяет его до

h[k] = h[k] + 1

Если h не имеет ключа k, это становится

h[k] = 0 + 1

Относительно снактического сахара, первое выражение гласит:

 h.[]=(k, h.[](k) + 1)

Это метод Hash # [] которое возвращает значение по умолчанию, а не метод Hash # [ ] =.

1
Cary Swoveland 8 Сен 2017 в 00:15

Я бы сделал что-то вроде этого:

array1.group_by(&:itself).select { |_, v| v.size >= 3 }.values.flatten
#=> [1,1,1]
2
spickermann 7 Сен 2017 в 16:23