Estoy tratando de lograr un comportamiento similar al _.get() de lodash, pero con la diferencia de que la función podrá revisar todas/cualquiera de las matrices en la ruta en lugar de especificar el índice en la ruta (es decir, 'abc.xyz[0] )
// Example 1 const _object = {abc: {xyz: [{value: 1}, {value: 2}]}}; console.log(accumulateValues(_object, 'abc.xyz.value'); // Desired output: [{value: 1}, {value: 2}] // Example 2 const _object = {abc: [{xyz: [{values: 1}]}]}; console.log(accumulateValues(_object, 'abc.xyz.values'); // Desired output: [1]Un enfoque bastante simple, si quiere [1, 2] fuera de eso, podría verse así:
const query = (path, ps = path .split ('.')) => (obj) => ps .reduce ((a, p) => a .flatMap (x => (x || {}) [p]) .filter (Boolean), [obj]) const _object = {abc: [{xyz: [{value: 1}, {value: 2}]}]} console .log (query ('abc.xyz.value') (_object)) Si está buscando [{value: 1}, {value: 2}] , probablemente no sería mucho más difícil. Pero si de alguna manera, como parece implicar la pregunta, desea cualquiera de los resultados, en función de cómo envuelve 'abc' , entonces realmente no entiendo sus requisitos.
Aquí, los corchetes que rodean algunos nodos (como [xyz] ) no agregan ningún valor, ya que simplemente asumimos que hay una matriz hasta abajo, envolviendo el valor inicial en uno. Si aún quisiera suministrarlos, podríamos eliminarlos antes de procesarlos:
const query = (path, ps = path .replace (/[\[\]]/g, '') .split ('.')) => (obj) => // ...Es posible que deseemos mejorar esto para tomar matrices en la raíz al verificar si la entrada ya era una matriz antes de envolverla en una. Lo dejo como ejercicio.
Aquí hay una solución usando object-scan . Es un poco más flexible, puede, por ejemplo, hacer coincidir atributos desconocidos con * o usar una expresión regular para hacer coincidir segmentos y mucho más (consulte la documentación).
.as-console-wrapper {max-height: 100% !important; top: 0} <script type="module"> import objectScan from 'https://cdn.jsdelivr.net/npm/object-scan@18.1.2/lib/index.min.js'; const f = (needle, obj) => objectScan([needle], { useArraySelector: false, rtn: 'value', reverse: false })(obj); const o1 = { abc: { xyz: [{ value: 1 }, { value: 2 }] } }; const r1a = f('abc.xyz', o1); console.log(r1a); // => [ { value: 1 }, { value: 2 } ] const r1b = f('abc.xyz.value', o1); console.log(r1b); // => [ 1, 2 ] const o2 = { abc: [{ xyz: [{ values: 1 }] }] }; const r2a = f('abc.xyz.values', o2); console.log(r2a); // => [ 1 ] const r2b = f('abc.*.values', o2); console.log(r2b); // => [ 1 ] </script>Descargo de responsabilidad: soy el autor de object-scan