配列から重複している値を返す

配列から重複している値を消すにはuniqメソッドを使えば一瞬で完了しますが、重複している値を返すメソッドは見つかりませんでした。

しかしgroup_byを使って以下のように取得できることを知りました!

 

irb(main):011:0> arry

=> [1546,1547,1549,1551,1552,1553,1554,1555,1556,1558,1559,1560,1561,1562,1563,1564,2962,5033,5986,6017,6018,6019,6226,8806,8807,8808,8809,8810,8811,8812,8813,8814,8815,8816,8900,10533,13355,13356,13357,14636,14636,15533,15533,15535,15535,15537,15537,16633,16633,19594,19594,19596,19596,20173,20173]

 
irb(main):015:0> arry.group_by{ |i| i }.reject{ |k,v| v.one? }.keys

=> [14636,15533,15535,15537,16633,19594,19596,20173]

 

 
重複している値が返るまでの過程

やり方がわかっただけではよくないと思ったので、各メソッドで何がどうなっているのか調べました。


group_byで配列をkey => valueにまとめる

irb(main):002:0> arry.group_by{|i|i}

=> {1546=>[1546],1547=>[1547],1549=>[1549],1551=>[1551],1552=>[1552],1553=>[1553],1554=>[1554],1555=>[1555],1556=>[1556],1558=>[1558],1559=>[1559],1560=>[1560],1561=>[1561],1562=>[1562],1563=>[1563],1564=>[1564],2962=>[2962],5033=>[5033],5986=>[5986],6017=>[6017],6018=>[6018],6019=>[6019],6226=>[6226],8806=>[8806],8807=>[8807],8808=>[8808],8809=>[8809],8810=>[8810],8811=>[8811],8812=>[8812],8813=>[8813],8814=>[8814],8815=>[8815],8816=>[8816],8900=>[8900],10533=>[10533],13355=>[13355],13356=>[13356],13357=>[13357],14636=>[14636,14636],15533=>[15533,15533],15535=>[15535,15535],15537=>[15537,15537],16633=>[16633,16633],19594=>[19594,19594],19596=>[19596,19596],20173=>[20173,20173]}

 


rejectvalueが1であるものを取り除く

irb(main):003:0> arry.group_by{ |i| i }.reject{ |k,v| v.one? }

=> {14636=>[14636,14636],15533=>[15533,15533],15535=>[15535,15535],15537=>[15537,15537],16633=>[16633,16633],19594=>[19594,19594],19596=>[19596,19596],20173=>[20173,20173]}

 

keysでキーを取り出す
その後残ったもののキーを取り出せば重複している値を返してくれます!

irb(main):004:0> arry.group_by{|i|i}.reject{ |k,v| v.one? }.keys

=> [14636,15533,15535,15537,16633,19594,19596,20173]

 

  

感想その他

調べなくてもメソッドをサクッと使いこなせるようになりたい!!

きっと他のやり方も何パターンかあるはず!Ruby2.7からならtallyメソッドでもいけそう!