使用lodash的isEqual()排除一些属性

Mar*_*tos 25 javascript lodash

我正在使用_.isEqual来比较2个对象数组(例如:每个对象有10个属性),并且它工作正常.

现在有2个属性(创建和删除),我不需要成为比较的一部分.

例:

var obj1 = {name: "James", age: 17, creation: "13-02-2016", deletion: "13-04-2016"}
var obj2 = {name: "Maria", age: 17, creation: "13-02-2016", deletion: "13-04-2016"}

// lodash method...
_.isEqual(firstArray, secondArray)
Run Code Online (Sandbox Code Playgroud)

rye*_*lar 70

您可以使用omit()删除对象中的特定属性.

var result = _.isEqual(
  _.omit(obj1, ['creation', 'deletion']),
  _.omit(obj2, ['creation', 'deletion'])
);
Run Code Online (Sandbox Code Playgroud)

var obj1 = {
  name: "James",
  age: 17,
  creation: "13-02-2016",
  deletion: "13-04-2016"
};

var obj2 = {
  name: "Maria",
  age: 17,
  creation: "13-02-2016",
  deletion: "13-04-2016"
};

var result = _.isEqual(
  _.omit(obj1, ['creation', 'deletion']),
  _.omit(obj2, ['creation', 'deletion'])
);

console.log(result);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
Run Code Online (Sandbox Code Playgroud)


AJ *_*son 13

@ ryeballar的答案对于大型对象来说并不是很好,因为每次进行比较时都会创建每个对象的深层副本.

最好使用isEqualWith,例如

var result = _.isEqualWith(obj1, obj2, (value1, value2, key) => {
    return key === "creation" || key === "deletion" ? true : undefined;
});
Run Code Online (Sandbox Code Playgroud)

请注意,如果您是为ES5及更早版本编写的,则必须isEqualWith使用函数语法(_.isMatch())替换箭头语法()

  • 在Lodash 4.17.11上,仅当两个对象具有相同数量的键时,该键才起作用。否则,“ isEqualWith”将预先检查两个对象是否具有相同数量的键,并在进入下一个遍历每个键的循环之前返回“ false”。因此,如果一个对象具有创建密钥,而另一个对象没有创建密钥,则实际上它不会忽略该字段。 (2认同)

Ale*_*lov 6

_.omit创建对象的深层副本。如果您只需要排除根道具,最好使用例如解构赋值来创建浅拷贝

const x = { a: 4, b: [1, 2], c: 'foo' }
const y = { a: 4, b: [1, 2], c: 'bar' }

const { c: xC, ...xWithoutC } = x
const { c: yC, ...yWithoutC } = y

_.isEqual(xWithoutC, yWithoutC) // true
xWithoutC.b === x.b             // true, would be false if you use _.omit
Run Code Online (Sandbox Code Playgroud)

最好的方法是根本不创建副本(TypeScript):

function deepEqual(
  x?: object | null,
  y?: object | null,
  ignoreRootProps?: Set<string>
) {
  if (x == null || y == null) return x === y

  const keys = Object.keys(x)
  if (!_.isEqual(keys, Object.keys(y)) return false

  for (let key of keys) {
    if (ignoreRootProps && ignoreRootProps.has(key)) continue
    if (!_.isEqual(x[key], y[key])) return false
  }
  return true
}
Run Code Online (Sandbox Code Playgroud)


Hop*_*ama 5

您可以将数组映射到“已清理”的数组中,然后进行比较。

// Create a function, to do some cleaning of the objects.
var clean = function(obj) {
    return {name: obj.name, age: obj.age};
};

// Create two new arrays, which are mapped, 'cleaned' copies of the original arrays.
var array1 = firstArray.map(clean);
var array2 = secondArray.map(clean);

// Compare the new arrays.
_.isEqual(array1, array2);
Run Code Online (Sandbox Code Playgroud)

这样做的缺点是,clean如果对象需要任何新属性,则需要更新该函数。可以对其进行编辑,以删除两个不需要的属性。