web-dev-qa-db-fra.com

Exclure certaines propriétés en comparaison en utilisant isEqual () de lodash

J'utilise _.isEqual qui compare 2 tableaux d'objets (ex: 10 propriétés de chaque objet), et cela fonctionne bien. 

Maintenant, il y a 2 propriétés (création et suppression) que je n'ai pas besoin de faire partie de la comparaison.

Exemple:

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)
20
Marco Santos

Vous pouvez utiliser omit () pour supprimer des propriétés spécifiques dans un objet.

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

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);
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>

51
ryeballar

La réponse de @ ryeballar n'est pas excellente pour les objets volumineux car vous créez une copie détaillée de chaque objet à chaque fois que vous effectuez la comparaison.

Il vaut mieux utiliser isEqualWith , par exemple.

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

Notez que si vous écrivez pour ES5 et versions antérieures, vous devrez remplacer la syntaxe de la flèche (() => {) par la syntaxe de la fonction (function() {).

8
AJ Richardson

Vous pourriez mapper votre tableau dans un tableau "nettoyé", puis comparer ceux-ci.

// 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);

Cela a l'inconvénient que la fonction clean devra être mise à jour si les objets attendent de nouvelles propriétés. Il est possible de l'éditer pour qu'il supprime les deux propriétés indésirables.

3
Hopeful Llama

_.omit crée copie en profondeur de l'objet. Si vous avez besoin d'exclure uniquement les accessoires root, il est préférable de créer une copie superficielle en utilisant, par exemple, l'attribution de déstructuration :

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

La meilleure façon est de ne pas créer de copies du tout (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
}
2

Je vois deux options.

1) Faites une deuxième copie de chaque objet qui ne contient pas la création ou la date.

2) Parcourez toutes les propriétés et, en supposant que vous sachiez qu'elles ont toutes les deux les mêmes propriétés, essayez quelque chose comme ceci.

var x ={}
var y ={}
for (var property in x) {
if(property!="creation" || property!="deletion"){
if (x.hasOwnProperty(property)) {
        compare(x[property], y[property])
    }
}
}

Où compare () est une simple comparaison de chaîne ou d'objet. Si vous êtes certain des propriétés sur un ou les deux objets, vous pouvez simplifier ce code un peu plus, mais cela devrait fonctionner dans la plupart des cas.

0
master565