2011-12-10 4 views
2

Предположим, у меня есть массив [1,2,3,1,5,2]. Здесь 1 и 2 - повторяющиеся элементы. Я хочу получить новый массив [1,2].Как получить повторяющиеся элементы из массива ruby?

Как это сделать в рубине ??

+0

@mihai, спасибо, проголосовали за закрытие, теперь вы можете смело удалить свой ответ. – tokland

ответ

10
arr = [1,2,3,1,5,2] 
arr.group_by {|e| e}.map { |e| e[0] if e[1][1]}.compact 

Довольно некрасиво ... но делает работу без п + 1 задачи.

+3

Кроме того, возможно, более ясный 'arr.group_by {| v | v} .select {| k, v | v.count> 1} .keys' – d11wtq

+1

Я действительно начал с этой точной строки, но взял .count, чтобы сделать меньше операций для каждого элемента. – Pavling

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

Более длинное решение с использованием reduce должно быть быстрее.

arr.reduce [{}, []] do |(seen, out), cur| 
    case seen[cur] 
    when :seen then 
     [seen.merge({cur => :added}), out << cur] 
    when :added then 
     [seen, out] 
    else 
    [seen.merge({cur => :seen}), out] 
    end 
end.last 
+0

Я написал нечто похожее в дублированном вопросе: http://stackoverflow.com/a/8459032/188031. Но я вижу здесь некоторые проблемы: 1) вы используете объект массива для проверки контузии, который является O (n), хеш или набор будут более подходящими. 2) вы можете безопасно удалить 'uniq'. 3) Используйте расширение аргументов вместо acc [0]/acc [1]. – tokland

+0

@tokland, спасибо за комментарий. 1) Я переключился на «Хеш». 2) Нет, к сожалению нет. См. '[1,1,1]'. 3) Хорошая точка! – Jan

+0

После последнего изменения 'uniq' больше не требуется. – Jan

Смежные вопросы