2017-08-16 10 views
-2

JavaScriptオブジェクトは2セットあります。 object1とobject2を比較し、object1にあるがobject2にないすべてのキーのリストを取得したい。私は私を助けるためのリソースを探していますが、私は単純なオブジェクトの比較関数を見つけることに終わっただけです。私が比較したいオブジェクトには多くのネストがあります。私は一番下に例を挙げました。2つのJavaScriptオブジェクトのキーの比較

これらの2つのオブジェクトを比較する関数を作成するにはどうすればよいですか?柔軟性のある関数を作成することは可能ですか?オブジェクトが変更され、より多くの入れ子を含む場合にも機能しますか?

const object1 = { 
    "gender": "man", 
    "age": 33, 
    "origin": "USA", 
    "jobinfo": { 
     "type": "teacher", 
     "school": "Wisconsin" 
    }, 
    "children": [ 
     { 
      "name": "Daniel", 
      "age": 12, 
      "pets": [ 
       { 
        "type": "cat", 
        "name": "Willy", 
        "age": 2 
       }, 
       { 
        "type": "dog", 
        "name": "jimmie", 
        "age": 5 
       } 
      ] 
     }, 
     { 
      "name": "Martin", 
      "age": 14, 
      "pets": [ 
       { 
        "type": "bird", 
        "name": "wagner", 
        "age": 12 
       } 
      ] 
     } 
    ], 
    "hobbies": { 
     "type": "football", 
     "sponsor": { 
      "name": "Pepsi", 
      "sponsorAmount": 1000, 
      "contact": { 
       "name": "Leon", 
       "age": 59, 
       "children": [ 
        { 
         "name": "James", 
         "pets": [ 
          { 
           "type": "dog", 
           "age": 4 
          } 
         ] 
        } 
       ] 
      } 
     } 
    } 
} 

const object2 = { 
    "gender": "man", 
    "jobinfo": { 
     "type": "teacher" 
    }, 
    "children": [ 
     { 
      "name": "Daniel", 
      "age": 12, 
      "pets": [ 
       { 
        "type": "cat", 
        "name": "Willy", 
        "age": 2 
       }, 
       { 
        "type": "dog", 
        "name": "jimmie", 
        "age": 5 
       } 
      ] 
     } 
    ] 
} 

は、だから私はこれらの2つのオブジェクトを比較することによって、達成したいものを、オブジェクト1にあるキーで構成される配列の戻り値を持つように、この場合ですが、object2はありません。配列はこのようになります。

["age", "hobbies", "type", "sponsor", "name", "sponsorAmount", "contact", "name", "age", "children", "name", "pets", "type", "age"]. 

これまでのところ私がこれまでに得たことです。これは一種の働きです。しかし、年齢は入れ子にされたオブジェクトの複数に存在するプロパティなので、例えば年齢が表示されません。 jsfiddle:

+0

希望の結果を追加してくださいと何をしようとしています。おそらく一見の価値:[mcve]。 –

+0

申し訳ありませんが、私は今、より多くの情報で投稿を更新しました。フィードバックをお寄せいただきありがとうございます。 –

+0

配列のインデックスも必要ですか?あなたは繰り返しの順序で結果が必要ですか? –

答えて

0

感謝。 私はそれを解決し、ローマ人の答えから多くのインスピレーションを得ました。

const compareObjects = (obj1, obj2) => { 
    function getAllKeyNames(o, arr, str){ 
     Object.keys(o).forEach(function(k){ 
      if (Object.prototype.toString.call(o[k]) === "[object Object]") { 
       getAllKeyNames(o[k], arr, (str + '.' + k)); 
      } else if (Array.isArray(o[k])) { 
       o[k].forEach(function(v){ 
        getAllKeyNames(v, arr, (str + '.' + k)); 
       }); 
      } 
      arr.push(str + '.' + k); 
     }); 
    } 

    function diff(arr1, arr2) { 
     for(let i = 0; i < arr2.length; i++) { 
      arr1.splice(arr1.indexOf(arr2[i]), 1); 
     } 
     return arr1; 
    } 

    const o1Keys = []; 
    const o2Keys = []; 
    getAllKeyNames(obj1, o1Keys, ''); // get the keys from schema 
    getAllKeyNames(obj2, o2Keys, ''); // get the keys from uploaded file 

    const missingProps = diff(o1Keys, o2Keys); // calculate differences 
    for(let i = 0; i < missingProps.length; i++) { 
     missingProps[i] = missingProps[i].replace('.', ''); 
    } 
    return missingProps; 
} 

ここjsfiddle:https://jsfiddle.net/p9Lm8b53/

1

複雑なソリューション設定オブジェクトとカスタムgetAllKeyNames()再帰関数を使用して:私は、次のリソースを見て持っていたhttps://jsfiddle.net/rqdgojq2/

指定されたオブジェクトから一意のキー名をすべて取得する:

var object1 = {"gender":"man","age":33,"origin":"USA","jobinfo":{"type":"teacher","school":"Wisconsin"},"children":[{"name":"Daniel","age":12,"pets":[{"type":"cat","name":"Willy","age":2},{"type":"dog","name":"jimmie","age":5}]},{"name":"Martin","age":14,"pets":[{"type":"bird","name":"wagner","age":12}]}],"hobbies":{"type":"football","sponsor":{"name":"Pepsi","sponsorAmount":1000,"contact":{"name":"Leon","age":59,"children":[{"name":"James","pets":[{"type":"dog","age":4}]}]}}}}, 
 
    object2 = {"gender":"man","age":33,"origin":"USA","jobinfo":{"type":"teacher","school":"Wisconsin"},"children":[{"name":"Daniel","age":12,"pets":[{"type":"cat","name":"Willy","age":2},{"type":"dog","name":"jimmie","age":5}]}]}; 
 
    
 
    function getAllKeyNames(o, res){ 
 
     Object.keys(o).forEach(function(k){ 
 
      if (Object.prototype.toString.call(o[k]) === "[object Object]") { 
 
       getAllKeyNames(o[k], res); 
 
      } else if (Array.isArray(o[k])) { 
 
       o[k].forEach(function(v){ 
 
        getAllKeyNames(v, res); 
 
       }); 
 
      } 
 
      res.add(k); 
 
     }); 
 
    } 
 
    
 
    var o1Keys = new Set(), o2Keys = new Set(); 
 
    getAllKeyNames(object1, o1Keys); // unique keys of object1 
 
    getAllKeyNames(object2, o2Keys); // unique keys of object2 
 
    
 
    // get a list of all the keys that are in object1, but not in object2 
 
    var diff = [...o1Keys].filter((x) => !o2Keys.has(x)); 
 
    console.log(diff); 
 

+0

非常にきれいに見えますが、オブジェクトからすべてのキーを取得して比較する必要があります。オブジェクトに「年齢」という名前のキーが2つあり、他のオブジェクトに「年齢」という名前のキーが1つしかない場合、「年齢」キーが配列に追加されます。 このjsfiddleでは、object2から「age」を削除しましたが、配列に追加されません。 https://jsfiddle.net/4ze7ksx6/2/ –

0

あなたがカウントのためにオブジェクトを使用することができます。フィードバックのための

function getCount(object, keys, inc) { 
 
    Object.keys(object).forEach(function (k) { 
 
     if (!Array.isArray(object)) { 
 
      keys[k] = (keys[k] || 0) + inc; 
 
      if (!keys[k]) { 
 
       delete keys[k]; 
 
      } 
 
     } 
 
     if (object[k] && typeof object[k] === 'object') { 
 
      getCount(object[k], keys, inc) 
 
     } 
 
    }); 
 
} 
 

 
var object1 = { gender: "man", age: 33, origin: "USA", jobinfo: { type: "teacher", school: "Wisconsin" }, children: [{ name: "Daniel", age: 12, pets: [{ type: "cat", name: "Willy", age: 2 }, { type: "dog", name: "jimmie", age: 5 }] }, { name: "Martin", age: 14, pets: [{ type: "bird", name: "wagner", age: 12 }] }], hobbies: { type: "football", sponsor: { name: "Pepsi", sponsorAmount: 1000, contact: { name: "Leon", age: 59, children: [{ name: "James", pets: [{ type: "dog", age: 4 }] }] } } } }, 
 
    object2 = { gender: "man", jobinfo: { type: "teacher" }, children: [{ name: "Daniel", age: 12, pets: [{ type: "cat", name: "Willy", age: 2 }, { type: "dog", name: "jimmie", age: 5 }] }] }, 
 
    count = {}; 
 

 
getCount(object1, count, 1); 
 
getCount(object2, count, -1); 
 

 
console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }

関連する問題