извлечь ключевые значения, которые отличаются между двумя объектами (даже вложенными объектами), какой подход? - PullRequest
1 голос
/ 28 октября 2019

Я хотел бы сравнить два объекта, которые почти всегда будут иметь одинаковые свойства, и создать новый объект на основе свойств, значения которых отличаются от первого объекта. В приведенном ниже примере я хочу проверить, есть ли у inputData какой-либо ключ: значения, которые отличаются от currentData. затем создайте новый объект на основе этих ключей и значений. Надеюсь, это имеет смысл? какой подход я должен иметь? какой-нибудь рекурсивный Oject.assign? Распространить операцию? для цикла?

const currentData = {
  title: 'John',
  email: 'info@abc.com'
  address {
    street: 'myStreet 13'  
  }
}

const inputData = {
  title: 'Tom',
  email: 'info@abc.com',
  address {
    street: 'yourStreet 17'  
  }
}

Результат должен быть примерно таким:

const result = {
  title: 'Tom',
  address: {
    street: 'yourStreet 17'
  }   
}

1 Ответ

2 голосов
/ 28 октября 2019

Вам понадобится рекурсивная функция, проходящая по объектам, что-то вроде этого:

function compareObjects(a, b) {
    // Assume they'll be the same
    let result = null;
    // Keep track of the keys we've seen
    let keys = new Set();
    for (const key in a) {
        keys.add(key);
        if (!(key in b)) {
            // You'll want to decide what to do here, use `undefined`?
        } else {
            const avalue = a[key];
            const bvalue = b[key];
            if (avalue !== bvalue) {
                const aIsObject = typeof avalue === "object";
                const bIsObject = typeof bvalue === "object";
                if (aIsObject && bIsObject) {
                    // Both are objects, recurse
                    const update = compareObjects(avalue, bvalue);
                    if (update) {
                        result = result || {};
                        result[key] = update;
                    }
                } else {
                    // Different values
                    result = result || {};
                    result[key] = bvalue;
                }
            }
        }
    }
    // Add in any that are in `b` but weren't in `a`
    for (const key in b) {
        if (!keys.has(key)) {
            result = result || {};
            result[key] = b[key];
        }
    }
    return result;
}

Live Пример:

const currentData = {
    title: 'John',
    email: 'info@abc.com',
    address: {
        street: 'myStreet 13'  
    }
};

const inputData = {
    title: 'Tom',
    email: 'info@abc.com',
    address: {
        street: 'yourStreet 17'  
    }
};

function compareObjects(a, b) {
    // Assume they'll be the same
    let result = null;
    // Keep track of the keys we've seen
    let keys = new Set();
    for (const key in a) {
        keys.add(key);
        if (!(key in b)) {
            // You'll want to decide what to do here, use `undefined`?
        } else {
            const avalue = a[key];
            const bvalue = b[key];
            if (avalue !== bvalue) {
                const aIsObject = typeof avalue === "object";
                const bIsObject = typeof bvalue === "object";
                if (aIsObject && bIsObject) {
                    // Both are objects, recurse
                    const update = compareObjects(avalue, bvalue);
                    if (update) {
                        result = result || {};
                        result[key] = update;
                    }
                } else {
                    // Different values
                    result = result || {};
                    result[key] = bvalue;
                }
            }
        }
    }
    // Add in any that are in `b` but weren't in `a`
    for (const key in b) {
        if (!keys.has(key)) {
            result = result || {};
            result[key] = b[key];
        }
    }
    return result;
}

console.log(compareObjects(currentData, inputData));
...