- blogs:
- cles::blog
2014/10/31

Diff::LCS を使って自力で Diff を取る

テキストやソースコードの差分を取るのに diff コマンド*1を使うと便利ですが、今回はこれをちょっとした処理に使いたかったので Ruby 上で Enumerable なオブジェクト同士を比較できる Diff::LCS を使ってみました。これを使うと、Array などの差分情報が取得できるようになります。
Diff::LCS computes the difference between two Enumerable sequences using the McIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities to create a simple HTML diff output format and a standard diff-like tool.
例えば、[1,2,3] と [1,4,5,2,6,3] の差分を取るプログラムは下記のような感じになります。
require 'rubygems'
require 'diff/lcs'
from = [1,2,3]
to = [1,4,5,2,6,3]
diffs = Diff::LCS.diff(from,to)
p diffs
patched = Diff::LCS.patch(from, diffs)
p patched
これを実行すると下記のような差分と、patch の適用結果が得られます。
[[["+", 1, 4], ["+", 2, 5]], [["+", 4, 6]]]
[1, 4, 5, 2, 6, 3]
+ の部分が追加を表していて、削除する部分があれば - になるようです。
† ネストした Array はどうなる?
今回はネストした Array に適用したかったので以下のようなプログラムを試してみました。
require 'rubygems'
require 'diff/lcs'
from = [[1,2,3],[4,5,6],[7,8,9]]
to = [[1,2,3],[4,6],[7,8,9]]
diffs = Diff::LCS.diff(from,to)
p diffs
patched = Diff::LCS.patch(from, diffs)
p patched
んー、一応 patch は適用されるようですが、ネストした差分が得られるわけではないのですね。
[[["-", 1, [4, 5, 6]], ["+", 1, [4, 6]]]]
[[1, 2, 3], [4, 6], [7, 8, 9]]
このあたりは Diff::LCS.traverse_sequences を使って自分で処理を書けばできるのかもしれませんが、今日はここまで。
トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/7159
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form
コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。
OpenID を使ってログインすることができます。
サイト内検索
検索ワードランキング
へぇが多いエントリ
閲覧数が多いエントリ
1 . アーロンチェアのポスチャーフィットを修理(111562)
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(110214)
3 . 年次の人間ドックへ(109771)
4 . 2023 年分の確定申告完了!(1つめ)(109356)
5 . 三菱鉛筆がラミーを買収(109233)
2 . 福岡銀がデマの投稿者への刑事告訴を検討中(110214)
3 . 年次の人間ドックへ(109771)
4 . 2023 年分の確定申告完了!(1つめ)(109356)
5 . 三菱鉛筆がラミーを買収(109233)
cles::blogについて
Referrers