簡體   English   中英

比較兩個對象的值的最有效方法是什么?

[英]What's the most efficient way to compare values of two objects?

假設我有兩個對象,它們可能有一些共同的屬性。 總體思路是,將一個用作模式以將其與另一個進行比較。 我想比較常見屬性的值並構造一個新對象來表示每個單獨屬性的這些比較。 結果,任何共同的屬性都應該具有比較源屬性是否相等的值(例如result.abc = (obj1.abc == obj2.abc) )。 僅存在於兩個對象之一上的任何屬性都將以其原始值復制到結果中。

例如,考慮以下要比較的對象:

const schema = {
        num: 123,
        str: 'hello',
        nested: {
            num: 123,
            str: 'hello',
        },
    },

    doc = {
        nums: [1,2,3],
        str: 'hello',
        nested: {
            num: 123,
            str: 'world',
            foo: 'bar',
        },
    };

比較結果應該是:

{
    nums: [1,2,3], // obj2.nums
    num: 123,  // obj1.num
    str: true, // obj1.str == obj2.str
    nested: {
        num: true,  // obj1.nested.num == obj2.nested.num
        str: false, // obj1.nested.str == obj2.nested.str
        foo: 'bar', // obj2.nested.foo
    },
}

我將如何以最有效的時間和空間方式進行這種比較?

目前我有這個實現:

function deepCompare(obj1, obj2) {
    const validatedObject = {}

    Object.keys(obj1).forEach(e => {
        if(object[e].constructor.name === 'Object') {
            validatedObject[e] = deepCompare(obj1[e], obj2[e])
        } else {
            validatedObject[e] = obj1[e] === obj2[e]
        }
    })

    return validatedObject
}

是否有任何方法可以在不使用JSON.stringify的情況下更有效地執行此操作,因為我可能缺少屬性,但我仍然想返回values是正確的事實,盡管這些對象的架構是正確的?

也許for infor of循環? 但是我將如何測試它們的有效性呢? 小物體沒關系,但有時它們會變得非常大,我想以最有效的方式比較它們。

編輯注意

我知道這可能看起來像重復,但實際上並非如此,在這里我正在尋找一種最有效的方法來比較,迭代,遞歸或其他方式,而不是對象本身

邏輯是如果obj1有一個鍵並且obj2有相同的鍵,我們比較這些鍵的值

那么你應該使用

function compare(a, b) {
    if (a === b) return true;
    if (typeof a == 'object' && a != null && typeof b == 'object' && b != null) {
        return Object.keys(a).every(k =>
            !(k in b) || compare(a[k], b[k])
        );
    }
    return false;
}

我認為您的解決方案已經足夠好了,它只是缺少一些默認檢查(例如,如果您有相同的引用,則不需要遍歷對象鍵)。

此外,還有這個包聲稱是最快的深度相等檢查器。

在此處輸入圖像描述

您可以查看代碼以查看是否遺漏了任何其他條件(它仍然是對象的遞歸解決方案,但如果您感興趣,還可以在那里處理一些其他數據類型)。

如果您更喜歡書面材料而不是在遞歸調用之前有更多檢查的代碼,那么還有這篇文章

您要做的是首先找到公共對象鍵。 然后,當您遍歷屬性時,您希望在發現不匹配時立即返回 false。 在下面的代碼片段中,我使用了一個every循環,一旦一次迭代返回false就會停止。 如果在if塊中返回值,則不需要else塊。

 function deepCompare(obj1, obj2) { const commonKeys = Object.keys(obj1).filter(x => Object.keys(obj2).includes(x)); let valid = true; commonKeys.every(e => { if (obj1[e].constructor.name === 'Object') { console.log('object', e, obj1[e], obj2[e]) valid = deepCompare(obj1[e], obj2[e]) return valid // true goes to next, false ends the .every loop } console.log('not object', e, obj1[e] === obj2[e] ? 'match' : 'mismatch') valid = obj1[e] === obj2[e] return valid // true goes to next, false ends the .every loop }) return valid // returns the first false or true if everything passes } const obj1 = { num: 123, str: 'hello', nested: { num: 123, str: 'hello', } } const obj3 = { num: 1233, str: 'hello' } const obj4 = { num: 123, str: 'hello', nested: { num: 123, str: 'hellure', } } console.log(deepCompare(obj1, obj1.nested)) console.log(deepCompare(obj1, obj3)) console.log(deepCompare(obj1, obj4))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM