Estoy usando Angular y tengo datos de entrada en la siguiente estructura, clave = cadena, valor = matriz de cadenas:
inputObject= { 'employees': [ 'bob/january', 'bob/january-february', 'bob/january-march', 'steve/january', 'steve/january-february', 'steve/january-march', 'september', ],};
Necesito transformar este objeto dividiendo los valores usando '/' como delimitador, entonces dividiendo los elementos de la cadena en la matriz de empleados y colocándolos en un nuevo objeto donde el valor de la cadena antes de '/' se convierte en la clave del nuevo objeto. y los valores de cadena después de '/' se agregan como una matriz de valores de cadena. si el valor en el elemento de empleados no tiene un '/' en la cadena, entonces la clave debe ser un valor de cadena codificado como 'n/a' como se ve a continuación
Salida deseada:
outputObject = { 'bob': [ 'january', 'january-february', 'january-march' ], 'steve': [ 'january', 'january-february', 'january-march', ], 'n/a': 'september'}
Probé varias técnicas, un ejemplo como se ve en el fragmento donde intenté agregar a un mapa. Esto funcionaría agregando un nuevo objeto o cualquier otra estructura de datos que pueda recomendar.
inputObject= { 'employees': [ 'bob/january', 'bob/january-february', 'bob/january-march', 'steve/january', 'steve/january-february', 'steve/january-march', 'september', ], }; let outputMap = new Map(); let splitValues = inputObject.employees.map(a => a.split('/')); console.log(splitValues) splitValues.forEach(a => { if(a.length > 1){ outputMap.set(a[0], a[1]); } else { outputMap.set('n/a', a[0]) } }); console.log(outputMap)Stackblitz: https://stackblitz.com/edit/angular-ivy-ogbdwv
Puede usar Array.prototype.reduce() para agrupar elementos y String.prototype.match() para implementar la lógica de división:
const input = { employees: [ 'bob/january', 'bob/january-february', 'bob/january-march', 'steve/january', 'steve/january-february', 'steve/january-march', 'september', ] }, output = input.employees .reduce((acc, str) => { const [key = 'n/a', value] = str .match(/(([^/]+)\/)?(.+)/) .slice(2) const group = acc[key] group ? group.push(value) : acc[key] = [value] return acc }, {}) console.log(output) .as-console-wrapper{min-height:100%;}Reduce es perfecto para cambiar una estructura de datos a otra.
Podría verse así (no probado):
type Output = { [name:string]: string[] } const output = inputObject.employees.reduce<Output>((acc, curr) => { const splitStr = curr.split('/') if (splitStr.length === 1) { return { ...acc, 'n/a': [ ...acc['n/a'], splitStr[0] ] } } const [name, date] = splitStr; return { ...acc, [name]: acc[name]?.length > 0 ? [...acc[name], date] : [date] } }, {}); console.log(output);