লোডাসের সাথে 2 টি অবজেক্টের মধ্যে কীভাবে গভীর তুলনা করা যায়?


308

আমার কাছে ২ টি নেস্টেড অবজেক্ট রয়েছে যা আলাদা এবং আমার তাদের নেস্টেড প্রোপার্টিগুলির মধ্যে পার্থক্য রয়েছে কিনা তা আমার জানা দরকার।

var a = {};
var b = {};

a.prop1 = 2;
a.prop2 = { prop3: 2 };

b.prop1 = 2;
b.prop2 = { prop3: 3 };

আরও নেস্টেড বৈশিষ্ট্যগুলির সাথে অবজেক্টটি আরও জটিল হতে পারে। তবে এটি একটি ভাল উদাহরণ। আমার কাছে পুনরাবৃত্ত ফাংশন বা লোডাশ সহ কিছু ব্যবহার করার বিকল্প রয়েছে ...


গভীর তুলনার জন্য স্ট্যাকওভারফ্লো.com
পাভেল

7
_.isEqual(value, other)সেগুলি সমতুল্য কিনা তা নির্ধারণ করতে দুটি মানের মধ্যে একটি গভীর তুলনা সম্পাদন করে। লড্যাশ ডকস# আইসিসাল
লুকাশ লাইসিস

JSON.stringify ()
xgqfrms

10
JSON.stringify () ভুল: JSON.stringify ({a: 1, b: 2})! == JSON.stringify ({b: 2, a: 1})
Shl

উত্তর:


474

একটি সহজ এবং মার্জিত সমাধান ব্যবহার করা হয় _.isEqual, যা একটি গভীর তুলনা সম্পাদন করে:

var a = {};
var b = {};

a.prop1 = 2;
a.prop2 = { prop3: 2 };

b.prop1 = 2;
b.prop2 = { prop3: 3 };

_.isEqual(a, b); // returns false if different

যাইহোক, এই সমাধানটি কোন সম্পত্তিটি আলাদা তা দেখায় না।

http://jsfiddle.net/bdkeyn0h/


2
আমি জানি যে উত্তরটি বেশ পুরানো, তবে আমি যুক্ত করতে চাই, এটি _.isEqualবেশ জটিল হতে পারে। আপনি যদি বিষয়টিকে অনুলিপি করেন এবং কিছু মান পরিবর্তন করেন তবে এটি এখনও সত্য প্রদর্শিত হবে, কারণ রেফারেন্স একই the সুতরাং এই ফাংশনটি ব্যবহার করে এক হওয়া উচিত।
অরকডেসেল

23
@ আরকডেসেল যদি রেফারেন্স একই হয় তবে এটি একই জিনিস। সুতরাং এটি সমান। এটি পয়েন্টারটি লোড্যাশ নয় বরং জটিল। লোডাশ দুর্দান্ত।
লোক মোগ্রাবি

265

আপনার যদি কোন বৈশিষ্ট্য আলাদা হয় তা জানতে প্রয়োজন, () হ্রাস ব্যবহার করুন :

_.reduce(a, function(result, value, key) {
    return _.isEqual(value, b[key]) ?
        result : result.concat(key);
}, []);
// → [ "prop2" ]

36
মনে রাখবেন এটি কেবল প্রথম স্তরের বিভিন্ন বৈশিষ্ট্যকে আউটপুট দেবে। (সুতরাং এটি না সত্যিই গভীর বৈশিষ্ট্য যা আলাদা outputting অর্থে।)
আদমি

16
এছাড়াও, এটি বিতে থাকা বৈশিষ্ট্যগুলি গ্রহণ করবে না।
এড স্টাব

3
এবং _.reduce(a, (result, value, key) => _.isEqual(value, b[key]) ? result : result.concat(key), [])এক লাইনের ES6 সমাধানের জন্য
ডটগ্রিগ

1
কীটি শেষ করে এমন একটি সংস্করণ: মানlet edited = _.reduce(a, function(result, value, key) { return _.isEqual(value, b[key]) ? result : result.concat( { [key]: value } ); }, []);
অ্যালাইন মাতোস

47

এই থ্রেডে যে কেউ হোঁচট খাচ্ছে তার জন্য এখানে আরও একটি সম্পূর্ণ সমাধান রয়েছে। এটি দুটি অবজেক্টের তুলনা করবে এবং আপনাকে সমস্ত বৈশিষ্ট্যের চাবি দেবে যা হয় কেবলমাত্র বস্তু 1 এ , কেবল অবজেক্ট 2 এ , বা অবজেক্ট 1 এবং অবজেক্ট 2 এ উভয়ই রয়েছে তবে বিভিন্ন মান রয়েছে :

/*
 * Compare two objects by reducing an array of keys in obj1, having the
 * keys in obj2 as the intial value of the result. Key points:
 *
 * - All keys of obj2 are initially in the result.
 *
 * - If the loop finds a key (from obj1, remember) not in obj2, it adds
 *   it to the result.
 *
 * - If the loop finds a key that are both in obj1 and obj2, it compares
 *   the value. If it's the same value, the key is removed from the result.
 */
function getObjectDiff(obj1, obj2) {
    const diff = Object.keys(obj1).reduce((result, key) => {
        if (!obj2.hasOwnProperty(key)) {
            result.push(key);
        } else if (_.isEqual(obj1[key], obj2[key])) {
            const resultKeyIndex = result.indexOf(key);
            result.splice(resultKeyIndex, 1);
        }
        return result;
    }, Object.keys(obj2));

    return diff;
}

এখানে একটি উদাহরণ আউটপুট:

// Test
let obj1 = {
    a: 1,
    b: 2,
    c: { foo: 1, bar: 2},
    d: { baz: 1, bat: 2 }
}

let obj2 = {
    b: 2, 
    c: { foo: 1, bar: 'monkey'}, 
    d: { baz: 1, bat: 2 }
    e: 1
}
getObjectDiff(obj1, obj2)
// ["c", "e", "a"]

আপনি যদি নেস্টেড অবজেক্টগুলির বিষয়ে চিন্তা করেন না এবং লড্যাশ এড়িয়ে যেতে চান তবে আপনি _.isEqualএকটি সাধারণ মানের তুলনা যেমন বিকল্প হিসাবে রাখতে পারেন obj1[key] === obj2[key]


এই নির্বাচিত উত্তরটি কেবল সাম্য পরীক্ষার জন্য সঠিক। পার্থক্যগুলি কী তা আপনার যদি জানতে হবে তবে তাদের তালিকাভুক্ত করার কোনও সুস্পষ্ট উপায় নেই তবে এই উত্তরটি বেশ ভাল, কেবলমাত্র শীর্ষ-স্তরের সম্পত্তি কীগুলির একটি তালিকা দেওয়া যেখানে পার্থক্য রয়েছে। (এবং এটি একটি ফাংশন হিসাবে উত্তর দেয়, যা এটি ব্যবহারযোগ্য করে তোলে
সিগফ্রিড

এটি করা এবং কেবল _.isEqual (obj1, obj2) ব্যবহারের মধ্যে পার্থক্য কী? ওজনপ্রपर्টির জন্য চেক যুক্ত করা কি __isEqual হয় না? আমি এই ধারণার অধীনে ছিলাম যে objজেক্ট 1 এর এমন কোনও সম্পত্তি থাকলে যা ওজেক্ট 2-এর নেই, _.আইকুয়াল সত্যটি ফিরে আসবে না ..?
জেকেড 222

2
@ Jaked222 - পার্থক্য হল যে isEqual একটি বুলিয়ান আপনি কহন যদি বস্তু সমান বা না ফেরৎ, যখন উপরের ফাংশন আপনি বলে হয় কি দুটি বস্তুর মধ্যে পার্থক্য কী (যদি তারা ভিন্ন)। আপনি যদি কেবল দুটি বস্তু একই হয় কিনা তা জানতে আগ্রহী হন, ইস্কুল যথেষ্টই যথেষ্ট। যদিও অনেক ক্ষেত্রেই আপনি জানতে চান দুটি বস্তুর মধ্যে পার্থক্য কী। একটি উদাহরণ হতে পারে যদি আপনি কোনও কিছুর আগে এবং পরে পরিবর্তনগুলি সনাক্ত করতে চান এবং তারপরে পরিবর্তনের উপর ভিত্তি করে কোনও ইভেন্ট প্রেরণ করতে চান।
জোহান পারসসন

30

অ্যাডাম বোডুচের উত্তরের ভিত্তিতে , আমি এই ফাংশনটি লিখেছি যা গভীরতম সম্ভাব্য অর্থে দুটি বস্তুর তুলনা করে , পৃথক মান রয়েছে এমন পথগুলি ফেরত পাঠানোর পাশাপাশি একটি বা অন্য অবজেক্ট থেকে অনুপস্থিত পাথগুলি।

কোডটি দক্ষতার সাথে মাথায় রেখে লেখা হয়নি, এবং সে ক্ষেত্রে উন্নতি সর্বাধিক স্বাগত, তবে এখানে মূল ফর্মটি রয়েছে:

var compare = function (a, b) {

  var result = {
    different: [],
    missing_from_first: [],
    missing_from_second: []
  };

  _.reduce(a, function (result, value, key) {
    if (b.hasOwnProperty(key)) {
      if (_.isEqual(value, b[key])) {
        return result;
      } else {
        if (typeof (a[key]) != typeof ({}) || typeof (b[key]) != typeof ({})) {
          //dead end.
          result.different.push(key);
          return result;
        } else {
          var deeper = compare(a[key], b[key]);
          result.different = result.different.concat(_.map(deeper.different, (sub_path) => {
            return key + "." + sub_path;
          }));

          result.missing_from_second = result.missing_from_second.concat(_.map(deeper.missing_from_second, (sub_path) => {
            return key + "." + sub_path;
          }));

          result.missing_from_first = result.missing_from_first.concat(_.map(deeper.missing_from_first, (sub_path) => {
            return key + "." + sub_path;
          }));
          return result;
        }
      }
    } else {
      result.missing_from_second.push(key);
      return result;
    }
  }, result);

  _.reduce(b, function (result, value, key) {
    if (a.hasOwnProperty(key)) {
      return result;
    } else {
      result.missing_from_first.push(key);
      return result;
    }
  }, result);

  return result;
}

আপনি এই স্নিপেট ব্যবহার করে কোডটি চেষ্টা করতে পারেন (পূর্ণ পৃষ্ঠা মোডে চলমান প্রস্তাবিত):


4
আমি কেবল বাগটি স্থির করেছি, তবে আপনাকে জানাতে আপনার কোনও বস্তুর ভিতরে বা না b ব্যবহার করেb.hasOwnProperty(key)key in b কী অস্তিত্ব পরীক্ষা করতে হবে b[key] != undefined। পুরোনো সংস্করণ ব্যবহার সঙ্গে b[key] != undefined, ফাংশন ধারণকারী অবজেক্টের জন্য একটি ভুল পরিবর্তন ফিরে undefinedহিসাবে, compare({disabled: undefined}, {disabled: undefined})। আসলে, পুরানো সংস্করণেও সমস্যা ছিল null; আপনি সবসময় ব্যবহার করে যে মত সমস্যার এড়াতে পারেন ===এবং!== পরিবর্তে ==এবং !=
ররি ও'কেনে

23

এখানে একটি সংক্ষিপ্ত সমাধান:

_.differenceWith(a, b, _.isEqual);

7
আমার জন্য বস্তুর সাথে কাজ করে বলে মনে হচ্ছে না। পরিবর্তে একটি খালি অ্যারে ফেরত দেয়।
tomhughes

2
এছাড়াও Lodash 4.17.4 ছাড়াই ফাঁকা অ্যারের পেয়ে
aristidesfl

@ জেড.খুল্লাহ যদি এইভাবে কাজ করে তবে তা নথিভুক্ত নয়।
ব্রেন্ডন

1
@ ব্র্যান্ডন, @ থিগস, @ আরিস্টিডিফসফফ দুঃখিত, আমি জিনিসগুলি মিশ্রিত করেছি, এটি বস্তুর অ্যারে নিয়ে কাজ করে, তবে গভীর বস্তুর তুলনার জন্য নয়। দেখা যাচ্ছে যে দুটি পরামিতি অ্যারে না হলে লোডাশ কেবল ফিরে আসবে []
জেড খোলা

7

অন্যান্য জিনিসগুলির সাথে কীভাবে কোনও বস্তু আলাদা তা পুনরাবৃত্তভাবে দেখাতে আপনি _.isEqual এবং _.isPlainObject এর সাথে মিলিত _.ড্রেস ব্যবহার করতে পারেন । এক্ষেত্রে আপনি তুলনা করতে পারবেন কীভাবে একটি খ এর সাথে আলাদা বা কীভাবে খ এর সাথে আলাদা?

var a = {prop1: {prop1_1: 'text 1', prop1_2: 'text 2', prop1_3: [1, 2, 3]}, prop2: 2, prop3: 3};
var b = {prop1: {prop1_1: 'text 1', prop1_3: [1, 2]}, prop2: 2, prop3: 4};

var diff = function(obj1, obj2) {
  return _.reduce(obj1, function(result, value, key) {
    if (_.isPlainObject(value)) {
      result[key] = diff(value, obj2[key]);
    } else if (!_.isEqual(value, obj2[key])) {
      result[key] = value;
    }
    return result;
  }, {});
};

var res1 = diff(a, b);
var res2 = diff(b, a);
console.log(res1);
console.log(res2);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>


7

সাধারণ ব্যবহার _.isEqualপদ্ধতি, এটি সমস্ত তুলনার জন্য কাজ করবে ...

  • দ্রষ্টব্য: এই পদ্ধতিটি অ্যারে, অ্যারে বাফারস, বুলিয়ানস, * তারিখের অবজেক্টস, ত্রুটিযুক্ত বস্তু, মানচিত্র, সংখ্যা, Objectঅবজেক্টস, রেজেক্সেস, * সেটস, স্ট্রিং, সিম্বল এবং টাইপ করা অ্যারে তুলনা করে supports Objectঅবজেক্টগুলি তাদের নিজস্ব দ্বারা তুলনা করা হয়, উত্তরাধিকারসূত্রে প্রাপ্ত নয়, অসংখ্য গুণাবলী। ফাংশন এবং ডোম * নোড সমর্থিত নয়

আপনার যদি নীচে থাকে:

 const firstName = {name: "Alireza"};
 const otherName = {name: "Alireza"};

যদি আপনি না: _.isEqual(firstName, otherName);,

এটা সত্য ফিরে আসবে

এবং যদি const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};

যদি আপনি না: _.isEqual(firstName, fullName);,

মিথ্যা ফিরে আসবে


6

এই কোডটি এমন সমস্ত বৈশিষ্ট্য সহ একটি বস্তুকে ফেরত দেয় যার পৃথক মান এবং উভয় বস্তুর মান values পার্থক্য লগ করতে দরকারী।

var allkeys = _.union(_.keys(obj1), _.keys(obj2));
var difference = _.reduce(allkeys, function (result, key) {
  if ( !_.isEqual(obj1[key], obj2[key]) ) {
    result[key] = {obj1: obj1[key], obj2: obj2[key]}
  }
  return result;
}, {});

3

লোডাশ / আন্ডারস্কোর ব্যবহার না করে আমি এই কোডটি লিখেছি এবং অবজেক্ট 2 এর সাথে অবজেক্ট 1 এর গভীর তুলনা করার জন্য আমার পক্ষে ভাল কাজ করছি

function getObjectDiff(a, b) {
    var diffObj = {};
    if (Array.isArray(a)) {
        a.forEach(function(elem, index) {
            if (!Array.isArray(diffObj)) {
                diffObj = [];
            }
            diffObj[index] = getObjectDiff(elem, (b || [])[index]);
        });
    } else if (a != null && typeof a == 'object') {
        Object.keys(a).forEach(function(key) {
            if (Array.isArray(a[key])) {
                var arr = getObjectDiff(a[key], b[key]);
                if (!Array.isArray(arr)) {
                    arr = [];
                }
                arr.forEach(function(elem, index) {
                    if (!Array.isArray(diffObj[key])) {
                        diffObj[key] = [];
                    }
                    diffObj[key][index] = elem;
                });
            } else if (typeof a[key] == 'object') {
                diffObj[key] = getObjectDiff(a[key], b[key]);
            } else if (a[key] != (b || {})[key]) {
                diffObj[key] = a[key];
            } else if (a[key] == (b || {})[key]) {
                delete a[key];
            }
        });
    }
    Object.keys(diffObj).forEach(function(key) {
        if (typeof diffObj[key] == 'object' && JSON.stringify(diffObj[key]) == '{}') {
            delete diffObj[key];
        }
    });
    return diffObj;
}

3

চেক করতে (নেস্টেড) বৈশিষ্ট্যের টেম্পলেট ব্যবহার করে গভীর তুলনা করুন

function objetcsDeepEqualByTemplate(objectA, objectB, comparisonTemplate) {
  if (!objectA || !objectB) return false

  let areDifferent = false
  Object.keys(comparisonTemplate).some((key) => {
    if (typeof comparisonTemplate[key] === 'object') {
      areDifferent = !objetcsDeepEqualByTemplate(objectA[key], objectB[key], comparisonTemplate[key])
      return areDifferent
    } else if (comparisonTemplate[key] === true) {
      areDifferent = objectA[key] !== objectB[key]
      return areDifferent
    } else {
      return false
    }
  })

  return !areDifferent
}

const objA = { 
  a: 1,
  b: {
    a: 21,
    b: 22,
  },
  c: 3,
}

const objB = { 
  a: 1,
  b: {
    a: 21,
    b: 25,
  },
  c: true,
}

// template tells which props to compare
const comparisonTemplateA = {
  a: true,
  b: {
    a: true
  }
}
objetcsDeepEqualByTemplate(objA, objB, comparisonTemplateA)
// returns true

const comparisonTemplateB = {
  a: true,
  c: true
}
// returns false
objetcsDeepEqualByTemplate(objA, objB, comparisonTemplateB)

এটি কনসোলে কাজ করবে। প্রয়োজনে অ্যারে সমর্থন যোগ করা যেতে পারে


2

একটি গভীর পার্থক্য আউটপুট করতে আমি একটি অ্যাডাম বোডুচের কোডকে ছুরিকাঘাত করেছি - এটি সম্পূর্ণরূপে অনির্ধারিত তবে টুকরাগুলি এখানে রয়েছে:

function diff (obj1, obj2, path) {
    obj1 = obj1 || {};
    obj2 = obj2 || {};

    return _.reduce(obj1, function(result, value, key) {
        var p = path ? path + '.' + key : key;
        if (_.isObject(value)) {
            var d = diff(value, obj2[key], p);
            return d.length ? result.concat(d) : result;
        }
        return _.isEqual(value, obj2[key]) ? result : result.concat(p);
    }, []);
}

diff({ foo: 'lol', bar: { baz: true }}, {}) // returns ["foo", "bar.baz"]

1
কবজির মতো কাজ করে, কেবল এজ 1 এবং অজেজ 2 এর ক্রম গুরুত্বপূর্ণ। উদাহরণস্বরূপ: diff({}, { foo: 'lol', bar: { baz: true }}) // returns []
amangpt777

2

যেমনটি জিজ্ঞাসা করা হয়েছিল, এখানে একটি পুনরাবৃত্ত বস্তুর তুলনা ফাংশন। এবং আরও কিছু। এই ধরণের ফাংশনটির প্রাথমিক ব্যবহারটি অবজেক্ট ইন্সপেকশন বলে ধরে নেওয়া, আমার কিছু বলার আছে। সম্পূর্ণ পার্থক্য তুলনা একটি খারাপ ধারণা যখন কিছু পার্থক্য অপ্রাসঙ্গিক হয়। উদাহরণস্বরূপ, টিডিডি জোরের মধ্যে অন্ধ গভীর তুলনা পরীক্ষাগুলি অপ্রয়োজনীয় ভঙ্গুর করে তোলে। যে কারণে, আমি আরও অনেক মূল্যবান আংশিক পার্থক্য প্রবর্তন করতে চাই । এটি এই থ্রেডটিতে পূর্ববর্তী অবদানের পুনরাবৃত্তিমূলক এনালগ। এটা তোলে কী উপস্থিত না উপেক্ষা করে একটি

var bdiff = (a, b) =>
    _.reduce(a, (res, val, key) =>
        res.concat((_.isPlainObject(val) || _.isArray(val)) && b
            ? bdiff(val, b[key]).map(x => key + '.' + x) 
            : (!b || val != b[key] ? [key] : [])),
        []);

বিডিফ অন্যান্য সম্পত্তি সহ্য করার সময় প্রত্যাশিত মানগুলি পরীক্ষা করার অনুমতি দেয়, যা আপনি স্বয়ংক্রিয় পরিদর্শন করতে চান । এটি সমস্ত ধরণের উন্নত প্রতিস্থাপনগুলি তৈরি করতে দেয়। উদাহরণ স্বরূপ:

var diff = bdiff(expected, actual);
// all expected properties match
console.assert(diff.length == 0, "Objects differ", diff, expected, actual);
// controlled inequality
console.assert(diff.length < 3, "Too many differences", diff, expected, actual);

সম্পূর্ণ সমাধান ফিরে। বিডিফের সাথে একটি সম্পূর্ণ traditionalতিহ্যবাহী ডিফ নির্মাণ করা তুচ্ছ:

function diff(a, b) {
    var u = bdiff(a, b), v = bdiff(b, a);
    return u.filter(x=>!v.includes(x)).map(x=>' < ' + x)
    .concat(u.filter(x=>v.includes(x)).map(x=>' | ' + x))
    .concat(v.filter(x=>!u.includes(x)).map(x=>' > ' + x));
};

দুটি জটিল বস্তুর উপরে উপরের ক্রিয়াকলাপটি এর অনুরূপ কিছু আউটপুট এনে দেবে:

 [
  " < components.0.components.1.components.1.isNew",
  " < components.0.cryptoKey",
  " | components.0.components.2.components.2.components.2.FFT.min",
  " | components.0.components.2.components.2.components.2.FFT.max",
  " > components.0.components.1.components.1.merkleTree",
  " > components.0.components.2.components.2.components.2.merkleTree",
  " > components.0.components.3.FFTResult"
 ]

পরিশেষে, মানগুলি কীভাবে পৃথক হয় তার এক ঝলক দেখতে আমরা সরাসরি ()) ডিফার্ট আউটপুটটি দেখতে চাই। তার জন্য, আমাদের বিডিফের একটি কুরুচিপূর্ণ সংস্করণ দরকার যা সিনথেটিকভাবে সঠিক পাথকে আউটপুট করে:

// provides syntactically correct output
var bdiff = (a, b) =>
    _.reduce(a, (res, val, key) =>
        res.concat((_.isPlainObject(val) || _.isArray(val)) && b
            ? bdiff(val, b[key]).map(x => 
                key + (key.trim ? '':']') + (x.search(/^\d/)? '.':'[') + x)
            : (!b || val != b[key] ? [key + (key.trim ? '':']')] : [])),
        []);

// now we can eval output of the diff fuction that we left unchanged
diff(a, b).filter(x=>x[1] == '|').map(x=>[x].concat([a, b].map(y=>((z) =>eval('z.' + x.substr(3))).call(this, y)))));

এটি এর অনুরূপ কিছু আউটপুট দেবে:

[" | components[0].components[2].components[2].components[2].FFT.min", 0, 3]
[" | components[0].components[2].components[2].components[2].FFT.max", 100, 50]

এমআইটি লাইসেন্স;)


1

অ্যাডাম বোডুচের কাছ থেকে উত্তরটি সম্পূর্ণ করা, এটি বৈশিষ্ট্যগুলির মধ্যে পার্থক্য নেয়

const differenceOfKeys = (...objects) =>
  _.difference(...objects.map(obj => Object.keys(obj)));
const differenceObj = (a, b) => 
  _.reduce(a, (result, value, key) => (
    _.isEqual(value, b[key]) ? result : [...result, key]
  ), differenceOfKeys(b, a));

1

আপনার যদি কেবল মূল তুলনা প্রয়োজন:

 _.reduce(a, function(result, value, key) {
     return b[key] === undefined ? key : []
  }, []);

0

এখানে লড্যাশ গভীর পার্থক্য পরীক্ষক সহ একটি সাধারণ টাইপসক্রিপ্ট যা একটি পুরানো অবজেক্ট এবং একটি নতুন অবজেক্টের মধ্যে পার্থক্য সহ একটি নতুন অবজেক্ট তৈরি করবে।

উদাহরণস্বরূপ, যদি আমাদের থাকে:

const oldData = {a: 1, b: 2};
const newData = {a: 1, b: 3};

ফলাফলটি হ'ল:

const result: {b: 3};

এটি মাল্টি-লেভেল ডিপ অবজেক্টগুলির সাথেও সামঞ্জস্যপূর্ণ, অ্যারেগুলির জন্য এটি কিছু টুইট করার প্রয়োজন হতে পারে।

import * as _ from "lodash";

export const objectDeepDiff = (data: object | any, oldData: object | any) => {
  const record: any = {};
  Object.keys(data).forEach((key: string) => {
    // Checks that isn't an object and isn't equal
    if (!(typeof data[key] === "object" && _.isEqual(data[key], oldData[key]))) {
      record[key] = data[key];
    }
    // If is an object, and the object isn't equal
    if ((typeof data[key] === "object" && !_.isEqual(data[key], oldData[key]))) {
      record[key] = objectDeepDiff(data[key], oldData[key]);
    }
  });
  return record;
};

-1
var isEqual = function(f,s) {
  if (f === s) return true;

  if (Array.isArray(f)&&Array.isArray(s)) {
    return isEqual(f.sort(), s.sort());
  }
  if (_.isObject(f)) {
    return isEqual(f, s);
  }
  return _.isEqual(f, s);
};

এটি অবৈধ। আপনি ===সরাসরি সাথে বস্তুর তুলনা করতে পারবেন না , { a: 20 } === { a: 20 }মিথ্যা ফিরে আসবে, কারণ এটি প্রোটোটাইপের সাথে তুলনা করে। প্রাথমিকভাবে বস্তুর তুলনা করার আরও সঠিক উপায় হ'ল JSON.stringify()
এগুলিতে মুড়ে ফেলা

যদি (চ === গুলি) সত্য ফিরে আসে; - শুধুমাত্র পুনরাবৃত্তি জন্য। হ্যাঁ এ: 20} === {এ: 20 false মিথ্যা ফিরে আসবে এবং পরের শর্তে যাবে
ক্রুসেডার

কেন শুধু নয় _.isEqual(f, s)? :)
হার্গট

এটি একটি অসীম পুনরাবৃত্তি লুপের কারণ হবে কারণ যদি fকোনও বস্তু হয় এবং if (_.isObject(f))আপনি সহজেই ফাংশনটির মাধ্যমে ফিরে যান এবং সেই বিন্দুটিকে আবার আঘাত করেন। একই f (Array.isArray(f)&&Array.isArray(s))
20:

-2

এটি লড্যাশ ব্যবহার করে @ জেএলএভোইয়ের উপর ভিত্তি করে তৈরি হয়েছিল

let differences = function (newObj, oldObj) {
      return _.reduce(newObj, function (result, value, key) {
        if (!_.isEqual(value, oldObj[key])) {
          if (_.isArray(value)) {
            result[key] = []
            _.forEach(value, function (innerObjFrom1, index) {
              if (_.isNil(oldObj[key][index])) {
                result[key].push(innerObjFrom1)
              } else {
                let changes = differences(innerObjFrom1, oldObj[key][index])
                if (!_.isEmpty(changes)) {
                  result[key].push(changes)
                }
              }
            })
          } else if (_.isObject(value)) {
            result[key] = differences(value, oldObj[key])
          } else {
            result[key] = value
          }
        }
        return result
      }, {})
    }

https://jsfiddle.net/EmilianoBarboza/0g0sn3b9/8/


-2

শুধু ভ্যানিলা জেএস ব্যবহার করছি

let a = {};
let b = {};

a.prop1 = 2;
a.prop2 = { prop3: 2 };

b.prop1 = 2;
b.prop2 = { prop3: 3 };

JSON.stringify(a) === JSON.stringify(b);
// false
b.prop2 = { prop3: 2};

JSON.stringify(a) === JSON.stringify(b);
// true

এখানে চিত্র বর্ণনা লিখুন


1
এই পদ্ধতিটি আপনাকে বলে না যে কোন বৈশিষ্ট্যগুলি পৃথক।
জেএলভোই

2
এই ক্ষেত্রে, গুণাবলী আদেশে প্রভাবকে প্রভাবিত করে।
ভিক্টর অলিভিরা

-2

উপর নির্মাণের জন্য শ্রীধর Gudimela এর উত্তর , এখানে এটি একটি উপায় ফ্লো খুশি করতে পাবেন যে আপডেট করা হয়:

"use strict"; /* @flow */



//  E X P O R T

export const objectCompare = (objectA: any, objectB: any) => {
  let diffObj = {};

  switch(true) {
    case (Array.isArray(objectA)):
      objectA.forEach((elem, index) => {
        if (!Array.isArray(diffObj))
          diffObj = [];

        diffObj[index] = objectCompare(elem, (objectB || [])[index]);
      });

      break;

    case (objectA !== null && typeof objectA === "object"):
      Object.keys(objectA).forEach((key: any) => {
        if (Array.isArray(objectA[key])) {
          let arr = objectCompare(objectA[key], objectB[key]);

          if (!Array.isArray(arr))
            arr = [];

          arr.forEach((elem, index) => {
            if (!Array.isArray(diffObj[key]))
              diffObj[key] = [];

            diffObj[key][index] = elem;
          });
        } else if (typeof objectA[key] === "object")
          diffObj[key] = objectCompare(objectA[key], objectB[key]);
        else if (objectA[key] !== (objectB || {})[key])
          diffObj[key] = objectA[key];
        else if (objectA[key] === (objectB || {})[key])
          delete objectA[key];
      });

      break;

    default:
      break;
  }

  Object.keys(diffObj).forEach((key: any) => {
    if (typeof diffObj[key] === "object" && JSON.stringify(diffObj[key]) === "{}")
      delete diffObj[key];
  });

  return diffObj;
};
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.