He visto muchas respuestas sobre cómo eliminar duplicados, pero necesito lo contrario. Tengo una matriz con duplicados. Necesito formar una nueva matriz con solo los duplicados. Sin embargo, los duplicados son desconocidos y deben descubrirse primero para que todo el proceso esté automatizado.

    array = [{
    "name": "cat",
    "amount": 1
    }, {
    "name": "cat",
    "amount": 3
    }, {
    "name": "cat",
    "amount": 2
    }, {
    "name": "dog",
    "amount": 5
    }, {
    "name": "dog",
    "amount": 3
    }, {
    "name": "dog",
    "amount": 2
    }, {
    "name": "dog",
    "amount": 5
    }, {
    "name": "duck",
    "amount": 1
    }, {
    "name": "duck",
    "amount": 4
    }]

Luego, esto se vuelve aún más complicado porque cada duplicado debe insertarse en su propia matriz, y también un método preferible es que si hay más de 2 elementos en la matriz solo entonces esto se hará.

(El objetivo final aquí es calcular los totales en los duplicados, entonces ¿tal vez hay una mejor solución para esto?)

El resultado final debería ser algo como:

array1 = [{
    "name": "cat",
    "amount": 1
    }, {
    "name": "cat",
    "amount": 3
    }, {
    "name": "cat",
    "amount": 2
    }]

array2 = [{
    "name": "dog",
    "amount": 5
    }, {
    "name": "dog",
    "amount": 3
    }, {
    "name": "dog",
    "amount": 2
    }, {
    "name": "dog",
    "amount": 5
    }]

Pero el resultado final real es simplemente totalizar los duplicados, por lo tanto (pero ya puedo obtener esto si se pueden generar las matrices anteriores):

array = [{
    "name": "cat",
    "amount": 6
    }, {
    "name": "dog",
    "amount": 15
    }]

Intentando obtener este resultado en Javascript o PHP.

Lo más cerca que estoy hasta ahora es obtener los elementos únicos en una nueva matriz con PHP:

function get_duplicates ($array) {
    return array_unique( array_diff_assoc( $array, array_unique( $array ) ) );
}

Pero esto solo da lo que son los duplicados.

2
user7389736 9 sep. 2018 a las 10:35

4 respuestas

La mejor respuesta

Puede tomar un Map y obtener una matriz de matrices para los objetos agrupados.

var data = [{ name: "cat", amount: 1 }, { name: "cat", amount: 3 }, { name: "cat", amount: 2 }, { name: "dog", amount: 5 }, { name: "dog", amount: 3 }, { name: "dog", amount: 2 }, { name: "dog", amount: 5 }, { name: "duck", amount: 1 }, { name: "duck", amount: 4 }],
    result = Array.from(
        data.reduce((m, o) => m.set(o.name, (m.get(o.name) || []).concat(o)), new Map).values()
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0
Nina Scholz 9 sep. 2018 a las 07:47

Prueba esto:

var array = [{
    "name": "cat",
    "amount": 1
}, {
    "name": "cat",
    "amount": 3
}, {
    "name": "cat",
    "amount": 2
}, {
    "name": "dog",
    "amount": 5
}, {
    "name": "dog",
    "amount": 3
}, {
    "name": "dog",
    "amount": 2
}, {
    "name": "dog",
    "amount": 5
}, {
    "name": "duck",
    "amount": 1
}, {
    "name": "duck",
    "amount": 4
}];

var data = {};
for (var elem of array) {
    data[elem.name] = data[elem.name] || []
    if (data[elem.name]) {
        data[elem.name].push(elem);
    } else {
        data[elem.name] = [elem];
    }
}

var result = [];

for (var key in data) {
    var amounts = 0;
    for (var elem of data[key]) {
        amounts += elem.amount;
    }
    result.push({
        name: key,
        amount: amounts
    });
}


console.log(result);
// [{
//     "name": "cat",
//     "amount": 6
// }, {
//     "name": "dog",
//     "amount": 15
// }, {
//     "name": "duck",
//     "amount": 5
// }]
1
Hongarc 9 sep. 2018 a las 08:20

¿Que tal este? Podría ser refactorizado definitivamente, pero entenderás la idea :)

const dupa = array.reduce((acc, { name, amount }) => {
  if (acc[name]) {
    return { ...acc, [name]: { amount: acc[name].amount + amount, count: acc[name].count += 1 }};
  }
  return { ...acc, [name]: { amount, count: 1}};
}, {});

const jaje = Object.keys(dupa)
  .filter(key => dupa[key].count > 2)
  .map(key => {
    return { name: key, amount: dupa[key].amount }    
})

console.log(jaje)

Pluma de trabajo aquí. https://codepen.io/_papiscript/pen/VGymjL?editors=0010

0
Papi 9 sep. 2018 a las 08:07

¿Qué pasa con llegar al resultado final directamente? empujar a una nueva matriz si no existe y acumular cantidad si ya existe

array = [{
    "name": "cat",
    "amount": 1
    }, {
    "name": "cat",
    "amount": 3
    }, {
    "name": "cat",
    "amount": 2
    }, {
    "name": "dog",
    "amount": 5
    }, {
    "name": "dog",
    "amount": 3
    }, {
    "name": "dog",
    "amount": 2
    }, {
    "name": "dog",
    "amount": 5
    }, {
    "name": "duck",
    "amount": 1
    }, {
    "name": "duck",
    "amount": 4
}];
let res = array.reduce((res, elem) => {
  let i = res.filter((e, i) => {
    if (e.name === elem.name) {
      e.amount += elem.amount
      return true
    }
    return false
  })
  if (i.length === 0) res.push(elem)
  return res
}, [])
console.log(res)
0
Chris Li 9 sep. 2018 a las 08:02