Actualmente estoy trabajando con matrices anidadas en una respuesta de API y hay información que necesito extraer.
En el siguiente ejemplo, quiero extraer los valores de la clave obj "PaymentTypeName", y mi código se ve así:
data.forEach(({ ModelList }) => { ModelList.forEach(({ CountryList }) => { CountryList.forEach(({ PaymentTypeList }) => { PaymentTypeList.forEach(({ PaymentTypeName }) => { console.log(PaymentTypeName); }); }); }); });Donde "datos" es mi respuesta API.
Quiero saber: ¿hay un enfoque de código mejor/más limpio que estas llamadas "forEach" anidadas? ¿Se considera una mala práctica?
Si puede simplificar la estructura de datos, ese será el mejor enfoque.
Si la estructura está fuera de su control, la forma en que la ha escrito está bien para una extracción 'única' de datos anidados. Sin embargo, si constantemente extrae datos anidados en diferentes rutas, escribir forEach() será laborioso y es posible que desee considerar una función auxiliar para hacerlo más fácil.
Escribí un ayudante que se ejecuta así:
const paymentTypes = getValuesAtPath(data, ['ModelList', 'CountryList', 'PaymentTypeList', 'PaymentTypeName']); La función en sí usa reduce() y es recursiva.
const data =[ { "ModelList": [ { "CountryList": [ { "PaymentTypeList": [ { "PaymentTypeName": "paypal" }, { "PaymentTypeName": "check" } ] }, { "PaymentTypeList": [ { "PaymentTypeName": "credit card" } ] } ] }, { "CountryList": [ { "AnotherInterestingField": "look at me", "PaymentTypeList": [ { "PaymentTypeName": "cash" } ] } ] } ] } ]; const getValuesAtPath = (data, path) => data.reduce((acc, item) => { const key = path[0]; const value = item[key]; if (value === undefined) return acc; // if at end of nested tree if (path.length === 1){ return [...acc, value]; } return [...acc, ...getValuesAtPath(value, path.slice(1, path.length))]; }, []); const result = getValuesAtPath(data, ['ModelList', 'CountryList', 'PaymentTypeList', 'PaymentTypeName']); console.log(result);Este ayudante ahora se puede reutilizar para extraer otras propiedades también:
getValuesAtPath(data, ['ModelList', 'CountryList', 'AnotherInterestingField'])