

rubyで配列の中の重複した値を取り出し、  
重複してる数が多い順に並び替えて配列として出力するにはどうしたらよいでしょうか。

`[1,2,3,4,5,6,7,8,9, 1,3,5,7,9, 1,3,5,7, 1,3,5, 1,3, 1]`  
↓  
`[1,3,5,7,9]`


CC BY-SA 3.0
2015-05-08T17:57:28.373
9960
2020-01-21T05:46:10.323
5855
question
ruby
rubyで配列の中の重複した値を取り出し、並び替える方法


以下のコードで実行できました。

[code]

    ary
    .select {|v| arr.count(v) > 1 }            # 要素数が複数個に満たないものを取り除く
    .sort {|a,b| arr.count(b) - arr.count(a) } # 要素数が多い順にソート
    .uniq                                      # 重複した値を取り除く
    
[/code]


CC BY-SA 3.0
2015-05-08T19:26:55.303
9961
2015-05-08T19:38:25.267
2015-05-08T19:38:25.267
8351
8351
9960
answer


こんな感じで、どうでしょう？

[code]

    arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 3, 5, 7, 9, 1, 3, 5, 7, 1, 3, 5, 1, 3, 1]
    arr.inject(Hash.new(1)) { |a, e| a[e] -= 1; a }.select { |k, v| v.nonzero? }.sort_by { |k, v| v }.map(&:first)    
    => [1, 3, 5, 7, 9] 
    
[/code]


CC BY-SA 3.0
2015-05-08T20:32:00.887
9965
2015-05-08T20:32:00.887
9508
9960
answer


書かれている仕様を愚直に処理してみました。

[code]

    require 'test/unit'
    
    def unique_ordered(list)
      list
        .group_by(&:itself)           # {1=>[1, 1, 1, 1, 1, 1], 2=>[2], 3=>[3, 3, 3, 3, 3], 4=>[4], 5=>[5, 5, 5, 5], 6=>[6], 7=>[7, 7, 7], 8=>[8], 9=>[9, 9]}
        .select { |_, v| v.size > 1 } # {1=>[1, 1, 1, 1, 1, 1], 3=>[3, 3, 3, 3, 3], 5=>[5, 5, 5, 5], 7=>[7, 7, 7], 9=>[9, 9]}
        .sort_by { |_, v| -v.size }   # [[1, [1, 1, 1, 1, 1, 1]], [3, [3, 3, 3, 3, 3]], [5, [5, 5, 5, 5]], [7, [7, 7, 7]], [9, [9, 9]]]
        .map(&:first)                 # [1, 3, 5, 7, 9]
    end
    
    class UniqueOrderedTest < Test::Unit::TestCase
      def test_unique_ordred
        input = [1,2,3,4,5,6,7,8,9, 1,3,5,7,9, 1,3,5,7, 1,3,5, 1,3, 1]
        assert_equal [1,3,5,7,9], unique_ordered(input)
      end
    end
    
[/code]


CC BY-SA 3.0
2015-05-08T21:38:13.083
9967
2015-05-08T21:45:49.037
2015-05-08T21:45:49.037
85
85
9960
answer


こんな感じでもいいかと思います。

[code]

    ary = [1,2,3,4,5,6,7,8,9, 1,3,5,7,9, 1,3,5,7, 1,3,5, 1,3, 1]
    ary
      .uniq
      .select {|v| ary.index(v) != ary.rindex(v) }
      .sort_by {|v| -ary.count(v) }
    
[/code]


CC BY-SA 3.0
2015-05-09T08:53:26.670
9985
2015-05-09T08:53:26.670
9608
9960
answer


Ruby2.7 の`tally`を使ってみました。

[code]

    arr = [1,2,3,4,5,6,7,8,9, 1,3,5,7,9, 1,3,5,7, 1,3,5, 1,3, 1]
    arr.tally.sort_by{|_,v| -v}.select{|i| i[1] > 1}.map(&:first)
    
[/code]

=> [1, 3, 5, 7, 9]


CC BY-SA 4.0
2020-01-21T05:46:10.323
62418
2020-01-21T05:46:10.323
32772
9960
answer