Estoy buscando una forma elegante (preferiblemente inmutable, lodash - ok) para compactar condicionalmente una matriz. Quiero verificar los duplicados de la combinación de los valores de la section y path , y agregar las ids de esos duplicados. tan dado
const arrayToBeCompacted = [ { section: "Section name 1", path: ["segment1", "segment2"], ids: ["id1"] }, { section: "Section name 1", path: ["segment1", "segment2"], ids: ["id2"] }, { section: "Section name2", path: ["segment1", "segment2"], ids: ["id3"] }, { section: "Another section", path: ["segment1", "segment2"], ids: ["id4"] }, { section: "Another section", path: ["segment1", "segment2"], ids: ["id5"] }, ]Como resultado me gustaría
const resultingArray = [ { section: "Section name 1", path: ["segment1", "segment2"], ids: ["id1", "id2"] }, { section: "Section name 2", path: ["segment1", "segment2"], ids: ["id3"] }, { section: "Another section", path: ["segment1", "segment2"], ids: ["id4", "id5"] }, ] Parece que lodash.uniq(By, With) y lodash.union(By, With) no son exactamente lo que estoy buscando.
Puedes hacerlo con reducir
const arrayToBeCompacted = [ { section: "Section name 1", path: ["segment1", "segment2"], ids: ["id1"] }, { section: "Section name 1", path: ["segment1", "segment2"], ids: ["id2"] }, { section: "Section name2", path: ["segment1", "segment2"], ids: ["id3"] }, { section: "Another section", path: ["segment1", "segment2"], ids: ["id4"] }, { section: "Another section", path: ["segment1", "segment2"], ids: ["id5"] }, ] const compacted = Object.values(arrayToBeCompacted.reduce((res, {section, path, ids}) => { const key = section + path.join('|') const existing = res[key] || {ids: [], section, path} existing.ids = [...existing.ids, ...ids] res[key] = existing return res }, {})) console.log(compacted)A continuación se muestra una forma posible de lograr el objetivo.
Fragmento de código
// method to compact array of objects const compactArr = arr => ( Object.values( // extract values from intermediate result-obj arr.reduce( // iterate over the array using "reduce" (acc, itm) => { // "acc" is the accumuator/aggregator const {section, ids, path} = itm; // de-structure to get props // construct uniq-key using "section" and "path" const uniqKey = `${section}-${path.join('-')}`; acc[uniqKey] = { ...(acc[uniqKey] || {}), section, path, // if "section" already exists, concat "ids" ids: (acc[uniqKey]?.ids ?? []).concat(ids) } return acc; }, {} // initial value of "acc" is empty-object {} ) ) // implicit return from method ); const arrayToBeCompacted = [{ section: "Section name 1", path: ["segment1", "segment2"], ids: ["id1"] }, { section: "Section name 1", path: ["segment1", "segment2"], ids: ["id2"] }, { section: "Section name2", path: ["segment1", "segment2"], ids: ["id3"] }, { section: "Another section", path: ["segment1", "segment2"], ids: ["id4"] }, { section: "Another section", path: ["segment1", "segment2"], ids: ["id5"] }, ]; console.log('compacted array: ', compactArr(arrayToBeCompacted)); .as-console-wrapper { max-height: 100% !important; top: 0 }Explicación
Comentarios en línea agregados en el fragmento anterior.