jQuery/JavaScript JSONオブジェクトの比較

2つのjsonオブジェクトのセットを比較することは可能ですか?私が持っているのは、jquery $ post()を介してJSONオブジェクトをポーリングするスクリプトです。私がしたいのは、ちょうどポーリングされたオブジェクトを取り出し、それを保存されたものと比較することです。どこから変更があっても、それが格納されたオブジェクトに適用されるか、または置き換えられる(いずれかの方法)が、私はUIの観点からJSONオブジェクトの変更をシームレスに適用します。 2.私はこれをしたいと思っています。なぜなら、UXの観点から見ると基本的には * *のように見えます。

私は2つのオブジェクトの間に違いがある場合は、その違いに固有のUIを編集する関数を呼び出すことができます。

7
これと同じように、おそらく json diff のようなものが必要です。
追加された 著者 Raynos,
あなたが間違っている、あなたはサーバーから同様のオブジェクトを送信しないで、クライアント側で手動で違いを見つける。差異を送信するにはのみする必要があります。帯域幅と計算時間を節約できます。
追加された 著者 Raynos,
@ Raynos JSON Diffは基本的に私が達成しようとしていることです。今では、自分のニーズに適用するのと同じロジックやアルゴリズムをどのように実現するかを理解するだけです。
追加された 著者 chris,
私が取り組んでいる作品のサーバー側のスペクトラムを支配していれば素晴らしいだろう。残念なことに、私はネットワーク上のさまざまな情報源からこのデータを引き出して、彼らが私に働きかけてくれた缶詰機能を教えてくれました。私の手が縛られているか、私はこれと違った方法で接近してきたでしょう。
追加された 著者 chris,

5 答え

私がしたいのは、ちょうどポーリングされたオブジェクトを取り出し、それを保存されたものと比較することです。どこから変更があった場合は、保存されたオブジェクトに適用するか、それを置き換えます(いずれかの方法で)

本当にシンプルな「どのように変更されましたか?はい/いいえ」解決策があれば、変更された場合は前のオブジェクトを新しいオブジェクトに置き換えます(引用した部分に基づいて)それを解析する前にJSONレスポンスを保存することができます。つまり、ウェブサーバーが送信する文字列形式で保存します。次に、次の応答が来たら、新しい文字列と古い文字列を比較します。それらが異なる場合(または最初のリクエストの場合)、JSONを解析し、適切に表示するために処理します。もちろんこれは、サーバー側のコードがJSON文字列を一貫した形式(プロパティの順序を変更しないなど)で作成していることを前提としています。

既に(解析された)オブジェクトを持っていると仮定した場合、 isEqual(a、b)関数は実際にネストされたオブジェクトや配列などのプロパティに対処する必要があります。これは再帰的に行うことができ、 trueまたはfalseを返しますが、 getDifferences(a、b)関数は、ネストされたオブジェクト内の違いをどのように報告するかを混乱させるでしょう。以下の簡単な例を考えてみましょう。

old: {"mum" : "Maria", "dad" : "Pierre", "kids" : ["Joe", "Mike", "Louisa"] }
new: {"mum" : "Julie", "dad" : "Pierre", "kids" : ["Joe", "Mary"] }

違いは {"mum": "Julie"、 "kids":["Mary"]} ですか? "ママ"は変更され、 "子供"のリストは変更されましたが、 "マイク"が "マリア"に変更されているか、 "マイク"と "ルイーザ"が "メアリー" ?おそらく、これは新しい値であるため、 "kids":["Joe"、 "Mary"] である必要があります。あなたはどのように削除を指示しますか?それは私があなたがその違いをどのように扱いたいと思うかわからない、頭の上の最初の例です。すばやく悪化する可能性があります。「子供」配列に文字列ではなくオブジェクトが含まれていて、家族ツリー全体を表す場合はどうでしょうか?新しい "mum"プロパティが ["Maria"、 "Julie"] (ステップ・ペアレントなどを許可する)の場合はどうなりますか?

あなたの特定のデータについて、あなたが1次元オブジェクトしか持っていないことを知っているなら、次のような簡単なことができます:

function getDifferences(oldObj, newObj) {
   var diff = {};

   for (var k in oldObj) {
      if (!(k in newObj))
         diff[k] = undefined; //property gone so explicitly set it undefined
      else if (oldObj[k] !== newObj[k])
         diff[k] = newObj[k]; //property in both but has changed
   }

   for (k in newObj) {
      if (!(k in oldObj))
         diff[k] = newObj[k];//property is new
   }

   return diff;
}

ネストされたオブジェクトを許可するための上記の最も単純な変更は、プロパティがオブジェクト/配列である場合、それがどのように異なっているかだけを気にして、どの「サブプロパティ」が変更されたかを正確に報告することはない。もしそうなら、単に上記の関数を取って変更してください:

else if (oldObj[k] !== newObj[k])

else if (!isEqual(oldObj[k],newObj[k]))

isEqual()は、ウェブ上に浮かぶ多数の比較関数の1つです。をStackOverflow に追加します。

(Note: I haven't bothered with .hasOwnProperty() above because I assume that objects that were returned に an Ajax request as JSON will not be inheriting properties from a proにtype chain. Similarly an isEqual() function for this purpose wouldn't need に worry about properties being functions, it only needs に worry about what is valid in a JSON string.)

9
追加された
私はこのexplinationを好きです。私は現在、新しいテスト環境を構築中です。だからこそ、私はこれに亀裂を与え、自分の必要に合わせて何ができるのかを見ていきたいと思っています。それが私のために動いたかどうかは、後で私の結果と一緒に戻ってくる。
追加された 著者 chris,

Sorry to answer old thread but my answer may help others who may face the same issue.the most easiest & shortest code to compare two json object as follows. thanks

<script type="text/javascript">
    $(document).ready(function() {
        var a = { "id": "210", "memberlist": "john" };
        var b = { "id": "210", "memberlist": "john1" };

        alert(JSON.stringify(a) != JSON.stringify(b) ? 'not same' : ' same');
    });
</script>
3
追加された
そうですが、私が思い出したことは、変化を検出し、その違いを判断することでした。私は正直なところ、4年前のようなものが何であったかを覚えていませんが、これについてコメントするには、文字通り同じかどうかは分かりません。アイデアのレベル大文字と小文字は同じですが、それでも大きなオブジェクトでは、これはクライアントに何らかの負担をかける可能性があります。より大きなオブジェクトを使用すると、クライアント側のメモリが大量に消費される可能性があります
追加された 著者 chris,
1
追加された
私はリンクダンピングが最近の答えであると聞きました。
追加された 著者 Raynos,
@WojciechBednarskiはさらに脇に、彼は平等チェックを望んでいない、彼は2つのオブジェクトの違いを見たいと思う。あなたはその質問にも答えなかった
追加された 著者 Raynos,
実際に2つの本質的に同じJSONオブジェクトを比較しようとしていますが、オブジェクトを指定する必要がありますが、プルには多かれ少なかれ含めることができますが、カウントの問題は別の方法で処理できます。私が理解しようとしていることは、相違点を見極めるために相手を比較して、それに応じて見つかった相違を処理するのが妥当であるかどうかです。
追加された 著者 chris,
Raynos、クリス問題を解決するアプローチが正しいかどうか議論することができます。しかし、答えはより多くのリンクを必要としない:]
追加された 著者 Wojciech Bednarski,
それにもかかわらず、これは良い提案であり、したがって+1です。
追加された 著者 Oh Chin Boon,
これは理論的に質問に答えるかもしれませんが、ここで答えの重要な部分を含めることと、リンクを提供することが望ましいでしょう。参考のため。
追加された 著者 Bill the Lizard,
私はクリスがこれとは違う何かを求めたと信じています。
追加された 著者 gilden,
var objectsAreEqual = function(obj1, x){
  var MAX_DEPTH = 10;
  var testEq = function(obj1, x, depth){
    if(depth < MAX_DEPTH){
      for (var p in obj1) {
          if(typeof(obj1[p]) !== typeof(x[p])) return false;
          if((obj1[p]===null) !== (x[p]===null)) return false;
          switch (typeof(obj1[p])) {
              case 'undefined':
                  if (typeof(x[p]) != 'undefined') return false;
                  break;
              case 'object':
                  if(obj1[p]!==null && x[p]!==null && (obj1[p].constructor.toString() !== x[p].constructor.toString() || !testEq(obj1[p], x[p], depth + 1))) return false;
                  break;
              case 'function':
                  if (p != 'equals' && obj1[p].toString() != x[p].toString()) return false;
                  break;
              default:
                  if (obj1[p] !== x[p]) return false;
          }
      }
    }
    return true;
  };
 //this is a little ugly, but the algorithm above fails the following: testEq([[1,2],[]], [[1,2],[1,3]], 0)
  return testEq(obj1, x, 0) && testEq(x, obj1, 0); 

};
0
追加された

1つの潜在的な解決策は、jQueryの拡張を使用することです。オブジェクトのプロパティが同じであれば、うまくいきます。

var newJSON = $.extend({},oldJSON,serverData);

次に、古いオブジェクトを保存し、新しいオブジェクトに存在しない場合は古いオブジェクトの任意のプロパティを持つ新しいオブジェクトを作成し、既存のプロパティをサーバーの新しいデータのプロパティで上書きします。

0
追加された
あなたは彼を誤解した。彼は何が変わったのかを知りたがっています。もし彼が後者を望んでいれば、 var newJSON = serverData
追加された 著者 Raynos,
それはどのように比較ですか?
追加された 著者 Raynos,
@nnnnnn - なぜあなたはそれらをマージしますか?あなたは代わりに新しいものを使うことができます。この答えは質問に全く答えません。それは手元の問題を理解する深い問題を示しています。
追加された 著者 vsync,
@Raynos - いいえ、質問から引用された賭けとして、OPは差異があるかどうかを判断し、「保存されたオブジェクトに適用するか、置き換える(いずれかの方法で)」と述べました。私は理想的な解決策が違いを報告することを意味するが、それができない場合(または簡単にできない場合)は、まっすぐの交換が受け入れられる。
追加された 著者 nnnnnn,
OPから "あるものから他のものへの変更があれば、それを格納されたオブジェクトに適用するか、または(どちらにしても)置き換える
追加された 著者 bstakes,
JavaScript - 日本のコミュニティ
JavaScript - 日本のコミュニティ
2 参加者の

日本人コミュニティのjavascript