配列から2個取り出したときの組み合わせを網羅

上のでカンが戻ったので、さらに実用的に。
「別名だが内容が完全一致するファイルは最初の1つを残して削除」したいとする。

対象となるファイルは、それぞれ自分自身以外のすべてのファイルと一致しているか検査されなくてはならない。

n個の要素から2個取り出したときの、すべての「組み合わせ」を網羅する必要がある。

長さnの配列に対して


(1,2),(1,3)・・・・(1,n)
(2,3),(2,4)・・・・(2,n)
(3,4),(3,5)・・・・(3,n)



(n-1,n)
のような形で組み合わせを返す、特殊なIteratorを実装してみる。

Arrayクラスの再定義。yieldでブロックオブジェクトに組み合わせの値を渡す。

class Array
  def each_comb
    i=0
    while i+1 < self.size
      j=1
      while i+j < self.size
        yield self[i], self[i+j]
        j+=1
      end
      i+=1
    end
  end
end

irbで実行してみる。

irb(main):015:0> a=[1,2,34,56,7,"b","po@@"]
=> [1, 2, 34, 56, 7, "b", "po@@"]
irb(main):016:0> a.each_comb{|a,b| puts "(#{a},#{b})"}
(1,2)
(1,34)
(1,56)
(1,7)
(1,b)
(1,po@@)
(2,34)
(2,56)
(2,7)
(2,b)
(2,po@@)
(34,56)
(34,7)
(34,b)
(34,po@@)
(56,7)
(56,b)
(56,po@@)
(7,b)
(7,po@@)
(b,po@@)
=> nil