Así que tengo este objeto y tengo que fusionarlo con el mismo ID de selección, pero también mantener el nombre del tema (y no sobrescribirlo)
[ { "selectionId":1, "topicName":"topic created or not validate" }, { "selectionId":1, "topicName":"hghhhg test test" }, { "selectionId":2, "topicName":"topic test" }, { "selectionId":3, "topicName":"new topic for test topic name and description name(test check)" }, { "selectionId":4, "topicName":"topic check check" }, { "selectionId":4, "topicName":"topic check popup" }, { "selectionId":5, "topicName":"test" } ]
Ahora quiero fusionar selectioId, pero también agregar topicName a una nueva matriz en el mismo objeto para que pueda hacer un bucle para que se muestre en consecuencia.
[ { "selectionId":1, ["topicName":"topic created or not validate", "topicName":"hghhhg test test"] } { "selectionId":2, "topicName":"topic test" }{ "selectionId":3, "topicName":"new topic for test topic name and description name(test check)" }{ "selectionId":4, ["topicName":"topic check check","topicName":"topic check popup"] }{ "selectionId":5, "topicName":"test" } ]
He intentado esto:
var result = list.filter(function(v) { return this[v.selectionId]? !Object.assign(this[v.selectionId], v): (this[v.selectionId] = v); }, {});
Respuesta: (No toma el topicName)
[ {selectionId: 1, topicName: "hghhhg test test"} {selectionId: 2, topicName: "topic test"} {selectionId: 3, topicName: "new topic for test topic name and description name(test check)"} {selectionId: 4, topicName: "topic check popup"} {selectionId: 5, topicName: "test"} ]
EDITAR: ¡Gracias chicos! ¡Todas las respuestas han funcionado! Y dando los resultados esperados.
Su ejemplo incluye una sintaxis no válida para una matriz.
["topicName":"topic check check","topicName":"topic check popup"]
Esto podría ser una matriz de objetos:
[{"topicName":"topic check check"},{"topicName":"topic check popup"}]
O más probablemente (cómo se basa mi ejemplo):
topicName: ["topic check check", "topic check popup"]
Debido a que no es una entrada uno a uno a la salida, es un buen uso de Array.prototype.reduce .
list.reduce((acc, row) => { const existingSel = acc.find(e => e.selectionId === row.selectionId); // If we don't have an entry, make one. if (!existingSel) { // Use expansion of row to avoid mutating source objects return [ ...acc, { ...row}]; } if (Array.isArray(existingSel.topicName)) { // if the topicName is an array, add to it. existingSel.topicName.push(row.topicName); } else { // Otherwise, make it an array with the two options. existingSel.topicName = [existingSel.topicName, row.topicName]; } return acc; }, []);
Si acerté con lo que espera como salida, puede hacer:
const input = [{ "selectionId": 1, "topicName": "topic created or not validate" }, { "selectionId": 1, "topicName": "hghhhg test test" }, { "selectionId": 2, "topicName": "topic test" }, { "selectionId": 3, "topicName": "new topic for test topic name and description name(test check)" }, { "selectionId": 4, "topicName": "topic check check" }, { "selectionId": 4, "topicName": "topic check popup" }, { "selectionId": 5, "topicName": "test" }]; const output = input.reduce((acc, item) => { const element = acc.find(elem => elem.selectionId === item.selectionId) if (element) { element.topicName = Array.isArray(element.topicName) ? element.topicName.push(item.topicName) : [element.topicName, item.topicName] } else { acc.push(item) } return acc; }, []); // test console.log(output);
De todos modos, le aconsejaría que no tenga diferentes tipos de datos para topicName
y que lo mantenga como una matriz, incluso si contiene solo un valor:
const input = [{ "selectionId": 1, "topicName": "topic created or not validate" }, { "selectionId": 1, "topicName": "hghhhg test test" }, { "selectionId": 2, "topicName": "topic test" }, { "selectionId": 3, "topicName": "new topic for test topic name and description name(test check)" }, { "selectionId": 4, "topicName": "topic check check" }, { "selectionId": 4, "topicName": "topic check popup" }, { "selectionId": 5, "topicName": "test" }]; const betterOutput = input.reduce((acc, item) => { const element = acc.find(elem => elem.selectionId === item.selectionId); if (element) { element.topicName.push(item.topicName); } else { acc.push({ selectionId: item.selectionId, topicName: [item.topicName] }) } return acc; }, []); // test console.log(betterOutput);
Puede usar Array.reduce()
para organizar la salida según el ID de selectionId
. La matriz de salida contiene objetos, cada uno con un ID de selección y una matriz de temas.
const input = [ { "selectionId":1, "topicName":"topic created or not validate" },{ "selectionId":1, "topicName":"hghhhg test test" },{ "selectionId":2, "topicName":"topic test" },{ "selectionId":3, "topicName":"new topic for test topic name and description name(test check)" },{ "selectionId":4, "topicName":"topic check check" },{ "selectionId":4, "topicName":"topic check popup" },{ "selectionId":5, "topicName":"test" } ] const output = Object.values(input.reduce((acc, cur) => { acc[cur.selectionId] = acc[cur.selectionId] || { selectionId: cur.selectionId, topics: []}; acc[cur.selectionId].topics.push({ topicName: cur.topicName}); return acc; }, {})) console.log('Output:', output);