Estoy tratando de crear una nueva Array of Object a partir de los datos, que es otra matriz de objetos que provienen de la API. La nueva matriz que obtendremos al final debe obtener valor de dataFromApi y los nombres de clave actualizados se seleccionarán de otra matriz que contenga la key anterior y el new key name | label para esas propiedades. Estos datos se exportarán en un archivo CSV. Entonces estamos usando componentes reutilizables para esta exportación, quiero hacer que esta conversión de datos sea dinámica. Como el nombre de la clave actual se parece a currentApplyStart y en el archivo CSV no son buenos encabezados.
Asi que,
Estamos obteniendo una nueva matriz de nombres clave de esta función. Lo que esta función intenta resolver es obtener el par de oldKeyName and its newKeyName || new key and label
const newKeyName = () => { if (data?.length) { const allColumn = Object.keys(data?.[0]); const columnKeys = dataColumns .filter((header) => allColumn.indexOf(header.key) >= 0) .map((column) => { return { key: column.key, label: column.label }; }); return columnKeys; }; }que devuelven algo como esto. Estos son datos de demostración.
let dataColumns = [ {key : 'color', label : 'newColor'} , {key : 'annoying', label : 'newAnnoying'}, key : 'height', label : 'newHeight'} // we only return these top three as the api data object consist only has these two keys in itself. {key : 'meta', label : 'newMeta'} {key : 'costApplyStart', label : 'CPA'} ] let newKeyNames = [ {key : 'color', label : 'newColor'} , {key : 'annoying', label : 'newAnnoying'}, {key : 'height', label : 'newHeight'} ] // as only these three key name exist in dataFromApi.Entonces, digamos que tenemos una matriz del objeto que proviene de la API
let DataFromApi = [ { color: 'red', annoying: true, height: 'unknown', }, { color: 'blue', annoying: false, height: 'unknown', }, { color: 'red', annoying: false, height: 'unknown', }, ];Los datos que quiero al final deberían ser así.
let finalData = [ {newColor: 'red',newAnnoying: true, newHeight: 'unknown',}, {newColor: 'blue',newAnnoying: false, newHeight: 'unknown',} { color: 'red', annoying: 'false, newHeight: 'unknown', }, ]Observe son datos, que cambié el nombre de la clave anterior a una nueva clave que quiero que sea el encabezado en csvFile. No puedo mutar los datos originales, por eso tengo que crear una nueva matriz de datos. La solución que probé fue esta, pero no estaba obteniendo el resultado deseado.
newKeyNames?.map((field) => { return dataFromAPi.map((item) => { if (item.hasOwnProperty(field.key)) { item[field.label] = item[field.key]; } }); });Basado en la explicación posterior, actualicé la respuesta.
Aquí está el enlace JSFiddle: https://jsfiddle.net/_ghost/py8et9vf/57/
let DataFromApi = [ { color: 'red', annoying: true, height: 'unknown', meta: { one: '1', two: '2'} }, { color: 'blue', annoying: false, height: 'unknown', meta: { one: '1', two: '2'} }, { color: 'red', annoying: true, height: 'unknown', meta: { one: '1', two: '2'} }, ]; let dataColumns = [ {key : 'color', label : 'newColor'} , {key : 'annoying', label : 'newAnnoying'}, {key : 'somekey', label : 'newSomeKey'}, {key : 'anotherKey', label : 'newAnotherKey'} ] function getAllDataCols(){ let obj = {}; // Make a new object from all the dataColums for ease of use dataColumns.forEach(item => { obj[item.key] = item.label }) return obj } function processDataFromApi(newDataCols){ let result = [] DataFromApi.forEach(obj => { let newObj = {} Object.keys(obj).forEach(name => { if(newDataCols[name] !== undefined){ //if we have an alternative for the name newObj[newDataCols[name]] = obj[name] }else{ // we don't have an alternative. use the already existing name newObj[name] = obj[name] } }) result.push(newObj) }) return result } let newDataCols = getAllDataCols() let response = processDataFromApi(newDataCols) console.log(response)En primer lugar, puede comenzar convirtiendo su matriz newKeyNames en un objeto o un mapa. Luego use Object.entries para destruir su objeto en pares [key,value] y luego aplique el cambio de nombre a estos pares y cree un nuevo objeto usando Object.fromEtnries a partir de estos pares.
let newKeyNames = new Map([{ key: 'color', label: 'newColor' }, { key: 'annoying', label: 'newAnnoying' }, { key: 'height', label: 'newHeight' } ].map(({ key, label }) => [key, label])); const dataFromApi = [{ color: 'red', annoying: true, height: 'unknown', }, { color: 'blue', annoying: false, height: 'unknown', }, { color: 'red', annoying: false, height: 'unknown', }, ]; const renamedObjectArray = dataFromApi.map(item => Object.fromEntries( Object.entries(item) .filter(([key, ]) => newKeyNames.get(key)) // this will filter out the properties that doesn't exist on newKeyNames map .map(([key, val]) => [newKeyNames.get(key), val]) // this will rebuild an object with renamed keys )); console.log(renamedObjectArray)