¿Cómo eliminar duplicados de una matriz de objetos usando ES6?

¿Cómo eliminar duplicados de una matriz de objetos usando ES6?

Me pregunto cuál sería el mejor método para fusionar 2 matrices de objetos itemsA y itemsB. Una vez combinados, los datos deben estar en mergedList.

Criterios:

  1. Los elementos con source='STAPLE' no deben repetirse en la matriz fusionada.
  2. Los artículos con cualquier otra fuente pueden repetirse. Por ejemplo, un elemento name: 'Ball' de source: 'USER' puede existir dos veces.

itemsA tiene 6 elementos, itemsB tiene 7 elementos y mergedList debería tener 11 elementos

let itemsA = [
{name: 'Milk', source: 'STAPLE'},
{name: 'Bread', source: 'AD'},
{name: 'Egg', source: 'STAPLE'},
{name: 'Ball', source: 'USER'},
{name: 'Pasta', source: 'STAPLE'},
{name: 'Coke', source: 'AD'}];
let itemsB = [
{name: 'Milk', source: 'USER'},
{name: 'Bread', source: 'AD'},
{name: 'Egg', source: 'STAPLE'},
{name: 'Ball', source: 'USER'},
{name: 'Mango', source: 'USER'},
{name: 'Pasta', source: 'STAPLE'},
{name: 'Coke', source: 'USER'}]

mergedList debe ser igual a

let mergedList = [
{name: 'Milk', source: 'STAPLE'},
{name: 'Bread', source: 'AD'},
{name: 'Egg', source: 'STAPLE'},
{name: 'Ball', source: 'USER'},
{name: 'Pasta', source: 'STAPLE'},
{name: 'Coke', source: 'AD'}] 
{name: 'Milk', source: 'USER'},
{name: 'Bread', source: 'AD'},
{name: 'Ball', source: 'USER'},
{name: 'Mango', source: 'USER'},
{name: 'Coke', source: 'USER'}]   ];
Mostrar la mejor respuesta

Me siento obligado a señalar que sus datos realmente no parecen tener sentido, al menos no desde la lógica que sugiere. Usted dice que quiere permitir que todo con solo "usuario" se repita, pero en su lista fusionada tiene cosas que no son "usuario" repitiendo. Dicho esto, ¿qué has probado?

@zfrisch Sí, lo siento, escribí mal los criterios, solo estaba tratando de dar un ejemplo. Tiene razón, cualquier fuente que no sea STAPLE puede repetir.

@zfrisch No, la pregunta dice que STAPLE no puede repetirse, pero los demás sí. la confusión proviene del hecho de que solo se dio un ejemplo, usuario.

concat luego reducir. simple.

function merge(itemsA, itemsB) {
  let merged = [];
  itemsA.concat(itemsB).reduce((stapleSet, obj) => (obj.source != "STAPLE") ?
  (merged.push(obj), stapleSet) : 
  (stapleSet.has(obj.name) || merged.push(obj), 
  stapleSet.add(obj.name), stapleSet), new Set());

  return merged;
}
  • obtener dos matrices.
  • cree una matriz fusionada para enviar objetos.
  • concatenar las dos matrices de elementos juntas.
  • reducir la matriz concatenada: si el origen del objeto es básico y no está en stapleSet, agregue el nombre del objeto a stapleSet: establezca que los objetos solo permitan uno de cada entrada -- luego empuje el objeto a la matriz merged. De lo contrario, empuje el objeto a la matriz merged.

  • devuelve la matriz fusionada de la función.

let itemsA = [
{name: 'Milk', source: 'STAPLE'},
{name: 'Bread', source: 'AD'},
{name: 'Egg', source: 'STAPLE'},
{name: 'Ball', source: 'USER'},
{name: 'Pasta', source: 'STAPLE'},
{name: 'Coke', source: 'AD'}];
let itemsB = [
{name: 'Milk', source: 'USER'},
{name: 'Bread', source: 'AD'},
{name: 'Egg', source: 'STAPLE'},
{name: 'Ball', source: 'USER'},
{name: 'Mango', source: 'USER'},
{name: 'Pasta', source: 'STAPLE'},
{name: 'Coke', source: 'USER'}];

    function merge(itemsA, itemsB) {
      let merged = [];
      itemsA.concat(itemsB).reduce((stapleSet, obj) => (obj.source != "STAPLE") ?
      (merged.push(obj), stapleSet) : 
      (stapleSet.has(obj.name) || merged.push(obj), 
      stapleSet.add(obj.name), stapleSet), new Set());

      return merged;
    }
    console.log( merge(itemsA, itemsB) );

Editar: formato If-Else para OP

function merge(itemsA, itemsB) {
  let merged = [];
  itemsA.concat(itemsB).reduce((stapleSet, obj) => {
    if (obj.source != "STAPLE") {
      merged.push(obj);
      return stapleSet;
    } else {
      if (stapleSet.has(obj.name)) {
        return stapleSet;
      } else {
        merged.push(obj);
        stapleSet.add(obj.name);
        return stapleSet;
      }
    }
  }, new Set());
  return merged;
}

Gracias por la respuesta, ¿cómo se escribiría esto en un bloque if-else?

@ aps5842 ¿a qué te refieres?

Quiero decir que la respuesta actual funciona pero está usando el operador ternario, me pregunto si se puede escribir lo mismo usando declaraciones if(){}else{}

@ aps5842 cualquier cosa que sea un ternario o un cortocircuito se puede reescribir como una declaración if else. Agregué a mi respuesta.