Ira が指摘したように、Levenshtein の方針に沿ったいくつかのオプションがありますが、オブジェクトをシリアル化し、それを辞書編集的に比較することを検討することになりますが、Ira が述べたように、探している JSON 固有の言語差分は考慮されません ( 2 つのツリーは同一の JSON である可能性がありますが、レーベンシュタイン距離が大きく異なります)。あなたが望むのは、間違いなく木の編集距離です。
したがって、ツリー編集距離の技術に関する詳細を追加すると、この分野で使用される既知のアルゴリズムは通常、たとえば Zhang & Shasha または Klein であり、Zhang & Shasha の Python 実装を見つけることができます。これらのアルゴリズムは、あるツリーを別のツリーに変換するための最小数の編集を取得し、差分を提供します。ただし、それらは最高でも O(n^2) とやや遅いため、多数の JSON オブジェクトまたはファイルを比較すると、ゴルフ ゲームを完成させ、皿洗い、洗濯、ペットの入浴などを行うことができます。家事雑務。
そして、これこそが Ira が語る芸術の真の姿なのです。なぜなら、この種のアルゴリズムは難しく、計算コストがかかるからです。だからあなたができることは、創造的になることです。1 つの方法は、比較するオブジェクトの数を絞り込むことです。たとえば、お互いよりも明らかに中間体に似ている 2 つの JSON オブジェクト間の編集距離を計算するのはなぜでしょうか? 辞書式比較によって同一のオブジェクトの編集距離を計算しないでください。2 つのオブジェクトが多少または劇的に異なる場合は、差分を忘れて、完全な置換が必要であるとだけ言ってください。
不必要な CPU サイクルを節約するツリー編集距離の「芸術」を適用するために必要なのは、「やや似ている」または「劇的に異なる」とは何を意味するかに関するメトリックを提供する方法です。
そのために、PQ-Gram ツリー編集距離近似アルゴリズム ( http://www.vldb2005.org/program/paper/wed/p301-augsten.pdf )の実装を作成しました。既存の PyGram Python コード ( https://github.com/Sycondaman/PyGram ) に基づくNode.js またはブラウザー ( https://github.com/hoonto/jqgram.git )。
PQ-Gram は、O(n log n) 時間と O(n) 空間 (n はノード数) で動作する真の編集距離アルゴリズムよりもはるかに高速です。
そのため、jqgram を使用して、JSON オブジェクトの編集距離メトリックに関して何を見ているのかをすばやく把握することをお勧めします。どのJSONオブジェクトを比較するか、単に置き換えるかを決定し、実際の距離を取得して差分を取得したい場合は、KleinまたはZhang&Shashaを使用して実際の差分を取得します。
以下は、github の jqgram 実装の README から直接引用した jqgram JSON オブジェクト ツリー編集距離近似の例です。
var jq = require("jqgram").jqgram;
var root1 = {
"thelabel": "a",
"thekids": [
{ "thelabel": "b",
"thekids": [
{ "thelabel": "c" },
{ "thelabel": "d" }
]},
{ "thelabel": "e" },
{ "thelabel": "f" }
]
}
var root2 = {
"name": "a",
"kiddos": [
{ "name": "b",
"kiddos": [
{ "name": "c" },
{ "name": "d" },
{ "name": "y" }
]},
{ "name": "e" },
{ "name": "x" }
]
}
jq.distance({
root: root1,
lfn: function(node){ return node.thelabel; },
cfn: function(node){ return node.thekids; }
},{
root: root2,
lfn: function(node){ return node.name; },
cfn: function(node){ return node.kiddos; }
},{ p:2, q:3, depth:10 },
function(result) {
console.log(result.distance);
});
lfn および cfn パラメーターは、各 JSON ツリーがノード ラベル名と各ツリー ルートの子配列を個別に決定する方法を指定します。これにより、さまざまなソースからの JSON オブジェクトを比較するなどの楽しいことができます。これらの関数を各ルートとともに提供するだけで、残りは jqgram が実行し、提供された lfn および cfn 関数を呼び出してツリーを構築します。