Tengo este tipo de conjunto de datos:
[ { CODMAT: '86 ', LIBMAT: 'Chariot N.50 Damien ', CODCAR: 'I050DCHE ', ZONLST: 'A', ALLLST: 1, CIRMAT1: 'AUA', CIRMAT2: 'SUC', CIRMAT3: 'SAL', CIRMAT4: 'AU3', CIRMAT5: ' ', CIRMAT6: ' ' }, { ... } ]Me gustaría concatenar todos los datos ' CIRMAT ' y eliminar estos que están vacíos, así:
{ CODMAT: '86 ', LIBMAT: 'Chariot N.50 Damien ', CODCAR: 'I050DCHE ', ZONLST: 'A', ALLLST: 1, CIRMAT: ['AUA','SUC','SAL','AU3'] }Gracias por tu ayuda
Puede usar Object.entries() , map() y reduce() juntos para lograr lo que desea.
La verificación de una cadena vacía se realiza mediante el uso de trim() que elimina los espacios en blanco iniciales y finales de la cadena y luego verifica la longitud de la cadena.
const input = [ { CODMAT: '86 ', LIBMAT: 'Chariot N.50 Damien ', CODCAR: 'I050DCHE ', ZONLST: 'A', ALLLST: 1, CIRMAT1: 'AUA', CIRMAT2: 'SUC', CIRMAT3: 'SAL', CIRMAT4: 'AU3', CIRMAT5: ' ', CIRMAT6: ' ' }, ] const output = input.map(item => ( Object.entries(item).reduce((newObj, [key, value]) => { if(key.startsWith("CIRMAT") && typeof value === "string"){ // ignore values that are "empty" if(value.trim().length === 0) return newObj; if(!newObj.CIRMAT) newObj.CIRMAT = [value]; else newObj.CIRMAT.push(value); } else{ // just assign the same key the same value newObj[key] = value; } return newObj; }, {}) )) console.log(output); .as-console-wrapper { max-height: 100% !important; top: 0; }map() para asignar cada valor en la matriz de input 1:1 a un valor en la matriz de output .reduce() hará la transformación de un solo elemento dentro de la matriz. Si la key comienza con CIRMAT , debemos verificar si ya tenemos una propiedad CIRMAT en nuestro objeto de trabajo newObj . Si no lo hemos hecho, esta es la primera propiedad de CIRMATx y necesitamos crear una matriz que contenga el value . Si ya tenemos una matriz y solo necesitamos push() el nuevo value . En caso de que la clave no comience con CIRMAT , simplemente agregamos el value y la key a nuestro objeto de trabajo newObj sin ningún cambio.Un enfoque que cubre el esquema de nomenclatura de cualquier key / nombre de propiedad que se fusionará generalmente necesita pasar por todas las entradas de un elemento (pares clave-valor) donde separaría cada key en su nombre de propiedad normalizado sin dígitos y solo su dígito parte del sufijo (el número final). Luego fusionaría/recopilaría solo las entradas que presentan tanto la nueva key como el number que se descartará donde, además, el value no está vacío (o solo una secuencia de espacios en blanco).
Por lo tanto, uno podría usar ...
una expresión regular como ... /^(\D+)(\d+)?$/ ... que coincide con el patrón de una cadena inicial sin dígitos y una cadena final de solo dígitos donde se capturan ambas subcadenas.
Array.prototype.map para crear una nueva matriz de elementos modificados/fusionados.
Object.entries para obtener los pares clave-valor de cada elemento de matriz que se asignará.
Array.prototype.reduce para procesar (combinar y/o recopilar) cada entrada del elemento de matriz que se mapeará.
function mergeEquallyNamedButNumberedEntries(item) { const regXNumberedKey = /^(\D+)(\d+)?$/; return Object .entries(item) .reduce((merger, [key, value]) => { const [ match, mergerKey = null, trailingNumber = null, ] = key.match(regXNumberedKey) ?? []; if (mergerKey !== null) { if (trailingNumber !== null) { if (String(value ?? null).trim() !== '') { (merger[mergerKey] ??= []).push(value); } } else { merger[mergerKey] = value; } } return merger; }, {}); } const sampleData = [{ CODMAT: '86 ', LIBMAT: 'Chariot N.50 Damien ', CODCAR: 'I050DCHE ', ZONLST: 'A', ALLLST: 1, CIRMAT1: 'AUA', CIRMAT2: 'SUC', CIRMAT3: 'SAL', CIRMAT4: 'AU3', CIRMAT5: ' ', CIRMAT6: ' ' }, { foo: 567, bar: 'baz', baz99: ' ', baz88: ' ', baz77: '', biz11: '', biz22: ' ', biz33: 'foo', }]; const result = sampleData .map(mergeEquallyNamedButNumberedEntries); console.log({ result, sampleData }); .as-console-wrapper { min-height: 100%!important; top: 0; }Esto debería funcionar :
const data = [ { CODMAT: '86 ', LIBMAT: 'Chariot N.50 Damien ', CODCAR: 'I050DCHE ', ZONLST: 'A', ALLLST: 1, CIRMAT1: 'AUA', CIRMAT2: 'SUC', CIRMAT3: 'SAL', CIRMAT4: 'AU3', CIRMAT5: ' ', CIRMAT6: ' ' }, ] const output = input.map(item => ( Object.entries(item).reduce((formatted, [key, value]) => { if(key.startsWith("CIRMAT") && typeof value === "string"){ if(value.trim().length === 0) return formatted; if(!formated.CIRMAT) formatted.CIRMAT = [value]; else formatted.CIRMAT.push(value); } else{ formatted[key] = value; } return formatted; }, {}) ))