任意の要素数の集合から重複を許さない配列を作る。もしくは.injectやら.reduceなどの使いどころ

前回のエントリで、途中でこんな感じでset型っぽいArrayを作った(共通部分取り出し的な感じ)
こんな感じ

def screen_name_sets(*args)
  id_lists = args.map do |usr_name|
    ids = client.follower_ids(usr_name)
    id_lists << ids.attrs.values.first
  end
  
  #ここ
  id_set = id_lists.first & id_list.last
end


もっとシンプルな例で言うと、以下のような感じになる

h = [1, 2, 3, 4]
k = [2, 3, 6, 4]
j = [2, 3, 5, 8]

some_array = [h, j, k]

some_array.first & some_array.last
#->[2, 3, 4]
#hとkの重複要素


しかし、 このArray.firstArray.lastを使うやり方だと、最初と最後の要素の重複部分しか作れない。 汎用性も無いし、真ん中の配列(この場合j= [2, 3, 5, 8])を同じように、セットに加えたい場合はどうしたらいいか。


答え


以下のようにすればいい。

h = [1, 2, 3, 4]
k = [2, 3, 6, 4]
j = [2, 3, 5, 8]

some_array = [h, j, k]

some_arary.reduce{|result, i| result & i}
#->[2, 3]

#これも同じ
some_arary.inject{|result, i| result & i}
#->[2, 3]

reduceとかのメソッドのイメージとしてはカリー化みたいに途中の結果を返し続ける感じなのかな。
今まではreduceやらfilterやらわからんのう、って感じだったが、こうやってみると結構便利なもんだな、って思う。