29

下に行かず、Javascriptまたはlodashのオブジェクト内のオブジェクトの内容を比較しない浅い比較を行う方法はありますか? 私はlodashをチェックしましたが、やりたくない深い比較を実行しているように見えることに注意してください。

var a = { x: 1, y: 2}
var b = { x: 1, y: 3}

たとえば、 と を比較する方法はありaますbか?

4

9 に答える 9

58

シンプルな ES6 アプローチ:

const shallowCompare = (obj1, obj2) =>
  Object.keys(obj1).length === Object.keys(obj2).length &&
  Object.keys(obj1).every(key => obj1[key] === obj2[key]);

ここで、次の比較のオブジェクト キー量の等価性チェックを追加しました (通常は考慮されない重要なケースです)。

shallowCompare({ x: 1, y: 3}, { x: 1, y: 3, a: 1}); // false

2019年アップデート。Andrew Rasmussen のコメントによると、ケースも考慮する必要がありますundefined。前のアプローチの問題は、次の比較が返されることtrueです。

({ foo: undefined })['foo'] === ({ bar: undefined })['foo'] // true

したがって、明示的なキーの存在チェックが必要です。そしてそれはで行うことができますhasOwnProperty

const shallowCompare = (obj1, obj2) =>
  Object.keys(obj1).length === Object.keys(obj2).length &&
  Object.keys(obj1).every(key => 
    obj2.hasOwnProperty(key) && obj1[key] === obj2[key]
  );
于 2018-09-14T00:27:02.823 に答える
5

Paul Draper のソリューションは、2 番目のパスで比較を削除することで最適化できます。

function areEqualShallow(a, b) {
  for (let key in a) {
    if (!(key in b) || a[key] !== b[key]) {
      return false;
    }
  }
  for (let key in b) {
    if (!(key in a)) {
      return false;
    }
  }
  return true;
}

于 2016-08-19T14:22:07.793 に答える
5

これはfbjsから持ち上げられます:

/**
 * Copyright (c) 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @typechecks
 *
 */

/*eslint-disable no-self-compare */

'use strict';

var hasOwnProperty = Object.prototype.hasOwnProperty;

/**
 * inlined Object.is polyfill to avoid requiring consumers ship their own
 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
 */
function is(x, y) {
    // SameValue algorithm
    if (x === y) {
        // Steps 1-5, 7-10
        // Steps 6.b-6.e: +0 != -0
        return x !== 0 || 1 / x === 1 / y;
    } else {
        // Step 6.a: NaN == NaN
        return x !== x && y !== y;
    }
}

/**
 * Performs equality by iterating through keys on an object and returning false
 * when any key has values which are not strictly equal between the arguments.
 * Returns true when the values of all keys are strictly equal.
 */
function shallowEqual(objA, objB) {
    if (is(objA, objB)) {
        return true;
    }

    if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
        return false;
    }

    var keysA = Object.keys(objA);
    var keysB = Object.keys(objB);

    if (keysA.length !== keysB.length) {
        return false;
    }

    // Test for A's keys different from B.
    for (var i = 0; i < keysA.length; i++) {
        if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
            return false;
        }
    }

    return true;
}

module.exports = shallowEqual;

使用する必要がある場合は、自分のプロジェクトにコピーすることをお勧めします。README には、lib 内のこれと他のコードを警告なしに削除または変更する可能性があることが明確に記載されているためです。

于 2016-06-05T01:57:07.403 に答える