Tengo una matriz "fuente"
source : [ { "id": 1, "secondId": 1 }, { "id": 2, "secondId": 1 }, { "id": 3, "secondId": 1 } ]Quiero cambiar el nombre del secondId cuando hay duplicados como este:
[ { "id": 1, "secondId": 1 }, { "id": 2, "secondId": 1_2 }, { "id": 3, "secondId": 1_3 } ]Tengo esto hasta ahora:
for (i = 0 ; i < source.length ; i++) { for (j = 0 ; j < source.length ; j++){ if (source[i]["id"] != source[j]["id"] && source[i]["secondId"] === source[j]["secondId"]){ source[j]["secondId"] += "_" + (i+1); } console.log(source[j]["secondId"]); } }y obtengo:
[ { "id": 1, "secondId": 1 }, { "id": 2, "secondId": 1_2 }, { "id": 3, "secondId": 1_2_3 } ]Traté de usar algunos:
if(source[j]["secondId"].includes("_"+ (i+1))){ console.log(source[j]["secondId"].split("_"+ (i+1)).shift()); }pero estoy recibiendo:
"segundoId": 1 "segundoId": 1 "segundoId": 1_2
¿Cómo puedo hacerlo? ¿Algún consejo, por favor?
Una versión que usa Array.reduce:
let source = [ { "id": 1, "secondId": 1 }, { "id": 2, "secondId": 1 }, { "id": 3, "secondId": 1 }]; let output = Object.values( source.reduce((a, e, i) => { let testId = e.secondId.toString(); if (a[testId]) { testId = testId.split("_")[0] + "_" + (i + 1); } a[testId] = {...e, secondId: testId}; return a; }, {}) ); console.log(output);Esta puede ser una solución para lograr el (supuesto) objetivo deseado:
Fragmento de código
const markDupes = arr => ( arr.reduce( (fin, {id, secondId}) => ({ tm: { [secondId]: (fin.tm[secondId] || 0) + 1 }, newArr: [ ...fin.newArr, {id, secondId: secondId.toString() + ( fin.tm[secondId] > 0 ? `_${fin.tm[secondId]+1}` : '' )} ] }), { tm: {}, newArr: [] } )?.newArr ); const source = [{ "id": 1, "secondId": 1 }, { "id": 2, "secondId": 1 }, { "id": 3, "secondId": 1 } ]; console.log(markDupes(source));Explicación
.reduce para iterar sobre la matriz de objetosfin inicial con dos props tm (mapa de seguimiento) y newArr (la matriz de resultados que tendrá el secondId actualizado según lo desee)id y secondIdtm según el secondId con un contadornewArr un objeto con id y secondId props con el último ( secondId ) convertido en una cadena para almacenar valores del formato 1_2 , 1_3 , etc.NOTA: Esta puede no ser una solución óptima.
Cuando convierte 1 a 1_2 o 1_3 , está convirtiendo un número en una cadena, lo que será un gran dolor cuando tenga un uso para el número más adelante. En cambio, lo que he hecho es convertir ese número a un decimal como 1.2 , 1.3 , lo que significa que puede hacer todo tipo de cálculos en un número sin mucha conversión.
let source = [ { "id": 1, "secondId": 1 }, { "id": 2, "secondId": 1 }, { "id": 3, "secondId": 1 } ]; let val = {}; for (const i in source) { let v = source[i].secondId val[v] = val[v] ? val[v] : v if (val[v] !== 1) { console.log(source[i].id, v); source[i].secondId = Number(v.toFixed(2)) + (val[v] * 0.1) } val[v]++ } console.log(source);si está realmente interesado en usar una cadena en su lugar, use
source[i].secondId = v+'_'+val[v]