2017-09-19 22 views
3

私は以下のように比較したい複雑なJSONオブジェクトを持っています:2つのオブジェクトを深い比較またはjson.stringifyと比較しますか?

$scope.new = [ 
    { 
    "name": "Node-1", 
    "isParent": true, 
    "text" : [ 
     { 
      "str" : "This is my first Node-1 string", 
      "parent":[] 
     }, 
     { 
      "str" : "This is my second Node-1 string", 
      "parent":[] 
     }], 
    "nodes": [ 
     { 
     "name": "Node-1-1", 
     "isParent": false, 
     "text" : [ 
      { 
      "str" : "This is my first Node-1-1 string", 
      "parent":[] 
      }, 
      { 
      "str" : "This is my second Node-1-1 string", 
      "parent":[] 
      }], 
      "nodes": [ 
      { 
      "name": "Node-1-1-1", 
      "isParent": false, 
      "text" : [ 
      { 
       "str" : "This is my first Node-1-1-1 string", 
       "parent":[] 
      }, 
      { 
       "str" : "This is my second Node-1-1-1 string", 
       "parent":[] 
      }], 
      "nodes": [] 
      } 
     ] 
     } 
    ] 
    } 
] 

をしかし、比較しながら、私も1つのプロパティを無視したいが、私はAngular.jsを使用していますように私は、のいずれかのオプションが表示されませんangular.equal 2つのオブジェクトを比較しながらそのプロパティを省略します。

console.log(angular.equals($scope.new,$scope.copy)); 

研究をしながらだから私はオプションを発するが、問題は、私はコピーを作成して省略し、私はlodashの場合のパフォーマンスの低下を持っているだろうと思い推測されたlodash使用している答え以下となりました。

Exclude some properties in comparison using isEqual() of lodash

だから今、私は、文字列にオブジェクトを変換してから比較を行うことを考えていますし、私はそれが速くなります推測するが、問題は、私は文字列比較しながら、そのプロパティを省略する方法ですか?

var str1 = JSON.stringify(JSON.stringify($scope.new)); 

var str2 = JSON.stringify(JSON.stringify($scope.copy)); 

console.log(str1==str2); 

注:私は2オブジェクトを比較しながらisParentプロパティを無視したい、このような

何か。

比較オブジェクト2を行う最良の方法は何ですか?

+1

あなただけの 'isParent'を無視するように探しています上のオブジェクト、またはすべての入れ子にされたオブジェクトにも同様に比較しますか? –

+0

@GuillermoMoratorio:比較するときにすべてのネストされたオブジェクトのisParentを無視したい –

答えて

1

あなたが_.isEqualWithを使用する場合はlodashを使用し、深い比較のために使用される標準的なコンパレータを上書きすることができます。

var objA = { 
 
    isParent: true, 
 
    foo: { 
 
    isParent: false, 
 
    bar: "foobar" 
 
    } 
 
}; 
 

 
var objB = { 
 
    isParent: false, 
 
    foo: { 
 
    isParent: true, 
 
    bar: "foobar" 
 
    } 
 
}; 
 

 
var comparator = function(left, right, key) { 
 
    if (key === 'isParent') return true; // if the key is 'isParent', mark the values equal 
 
    else return undefined;    // else fall back to the default behavior 
 
} 
 

 
var isEqual = _.isEqualWith(objA, objB, comparator); 
 

 
console.log(isEqual); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


は、複数のプロパティを除外し、それに応じてコンパレータ機能を拡張:

var comparator = function(left, right, key) { 
    if (key === 'isParent' || key === 'anotherKey') return true; 
    else return undefined; 
} 

また、あなたが好むものに応じて、構文的に多くの異なるアプローチを使用することができます - switch文、あなたが反復配列を...

+0

私を助けるためのあなたの親切な努力のためにUpvotedが、あなたはlodashとの深い比較が文字列の比較よりも速くなると思いますか? –

+0

パフォーマンスは実装に依存し、テストする必要があります。シリアライズは特に高速ではないので、文字列を比較するよりも遅くはないことは確かです。しかしそれを除けば、文字列比較の間に 'isParent'プロパティを無視することに対処しなければならないので、効果的に何も保存しません。 – Timo

+0

いいですが、2〜3のプロパティを含める場合はどうすればいいですか? –

2

は、文字列に変換これらのケースでは最良のアプローチではありません。 オブジェクトとして保管してください。

使用loadash:平野AngularJSを使用して

const propertiesToExclude = ['isParent']; 
let result = _.isEqual(
    _.omit(obj1, propertiesToExclude), 
    _.omit(obj2, propertiesToExclude) 
); 

は、ない必要なプロパティを削除するオブジェクトのコピーを作成し、それらを比較:

let firstObj = angular.copy(obj1); 
let secondObj = angular.copy(obj2); 
const propertiesToExclude = ['isParent']; 
function removeNotComparatedProperties(obj) { 
    propertiesToExclude.forEach(prop => { 
    delete obj[prop]; 
    }); 
} 

removeNotComparatedProperties(firstObj); 
removeNotComparatedProperties(secondObj); 
angular.equals(firstObj, secondObj); 
+0

私を助けてくれるあなたの親切な努力のためにアップアップされましたが、角度の場合に2オーバーヘッドを追加しています。解決策がより速くなる1つの事柄:ロダシュまたはアンヌカルのアプローチ? –

+0

あなたが使っているオブジェクトについては、パフォーマンスについての話はかなり役に立たないと言ってみましょう。比較のために除外するプロパティを持つ配列の長さと同じです。 Btw、ロードサムは内部で何をすると思いますか?マジック?それらはオブジェクトのプロパティをループし、渡されたプロパティでチェックします。 '_.omit'は、オブジェクトのコピー自体を作成します(' angular.copy'など)。 パフォーマンスはかなり同じでなければなりませんが、正確な回答が必要な場合は、jsperfを使用してコードをセットアップし、2つのケースのパフォーマンスをテストします。https://jsperf.com/ – quirimmo

+0

場合?場合によります。私がすでに使用している、またはどこか他の場所でloadashを使用する予定がある場合は、よりコンパクトで短いため、loadashソリューションを使用します。私はそれのためだけに負荷を含める必要がある場合は、私は2番目を通過するだろう。 – quirimmo

関連する問題