Necesito obtener los valores de todas las matrices que coincidan con la clave de items . Estoy creando un script en Javascript que necesita leer los objetos dentro de varias matrices de items en varios archivos json , pero cada json tiene una estructura diferente . Ejemplo:
archivo1.json:
{ "name":"First file", "randomName3874":{ "items":[ { "name":"item1" } ] }, "items":[ { "name":"randomItem2" } ] }archivo2.json
{ "name":"Another file", "randomName00000":{ "nestedItems":{ "items":[ { "name":"item87" } ] } }, "stuff":{ "items":[ { "name":"randomItem35" } ] } }Resultado deseado:
{ "data":[ { "items":[ { "name":"item1" } ] }, { "items":[ { "name":"randomItem2" } ] }, { "items":[ { "name":"item87" } ] }, { "items":[ { "name":"randomItem35" } ] } ] } En ambos archivos, quiero extraer las matrices que tienen los items clave. En los ejemplos anteriores, el script debería encontrar 4 matrices. Como puede ver en ambos archivos, cada matriz está anidada de manera diferente. ¿Cómo puedo hacer esto usando Javascript?
Esto lo hará:
function omit(key, obj) { const { [key]: omitted, ...rest } = obj; return rest; } function getItems(obj) { return (typeof obj === 'object' ? 'items' in obj ? [{ items: obj.items }].concat(getItems(omit('items', obj))) : Object.values(obj).map(v => getItems(v)) : [] ).flat() } console.log({ data: [file1, file2].map(o => getItems(o)).flat() })Véalo funcionando:
const file1 = { "name":"First file", "randomName3874":{ "items":[ { "name":"item1" } ] }, "items":[ { "name":"randomItem2" } ] } const file2 = { "name":"Another file", "randomName00000":{ "nestedItems":{ "items":[ { "name":"item87" } ] } }, "stuff":{ "items":[ { "name":"randomItem35" } ] } } function omit(key, obj) { const { [key]: omitted, ...rest } = obj; return rest; } function getItems(obj) { return (typeof obj === 'object' ? 'items' in obj ? [{ items: obj.items }].concat(getItems(omit('items', obj))) : Object.values(obj).map(v => getItems(v)) : [] ).flat() } console.log({ data: [file1, file2].map(o => getItems(o)).flat() })Vayamos un paso más allá y hagámoslo genérico (trabaje con una matriz de objetos y extraiga cualquier clave) y proporcionémoslo como una función, que también puede usar en otros proyectos:
function extractKey(objects, key) { const omit = (key, obj) => { const { [key]: omitted, ...rest } = obj; return rest; } const getValues = (obj) => (typeof obj === 'object' ? key in obj ? [{ [key]: obj[key] }].concat(getValues(omit(key, obj))) : Object.values(obj).map(o => getValues(o)) : [] ).flat(); return objects.map(o => getValues(o)).flat() } // use: extractKey([file1, file2], 'items');Véalo funcionando:
function extractKey(objects, key) { const omit = (key, obj) => { const { [key]: omitted, ...rest } = obj; return rest; } const getValues = (obj) => (typeof obj === 'object' ? key in obj ? [{ [key]: obj[key] }].concat(getValues(omit(key, obj))) : Object.values(obj).map(o => getValues(o)) : [] ).flat(); return objects.map(o => getValues(o)).flat() } // test: const file1 = { "name":"First file", "randomName3874":{ "items":[ { "name":"item1" } ] }, "items":[ { "name":"randomItem2" } ] } const file2 = { "name":"Another file", "randomName00000":{ "nestedItems":{ "items":[ { "name":"item87" } ] } }, "stuff":{ "items":[ { "name":"randomItem35" } ] } } console.log( { data: extractKey([file1, file2], 'items') } )Hacer un bucle como un bucle anidado en un árbol debería hacerlo.
let file1 = { "name": "First file", "randomName3874": { "items": [ { "name": "item1" } ] }, "items": [ { "name": "randomItem2" } ] } let file2 = { "name": "Another file", "randomName00000": { "nestedItems": { "items": [ { "name": "item87" } ] } }, "stuff": { "items": [ { "name": "randomItem35" } ] } } let itemsValues = []; let desiredKey = 'items' let loop = (value) => { if (Array.isArray(value)) { value.forEach(loop); } else if (typeof value === 'object' && value !== null) { Object.entries(value).forEach(([key, val]) => (key === desiredKey) ? itemsValues.push({ [desiredKey]: val }) : loop(val)); } } loop(file1); loop(file2); console.log(itemsValues);Esto debería funcionar:
function getIdInObjects(id, objects, output = { data: [] }) { if (id in objects) output.data.push({[id]: objects[id]}); for (const key in objects) { if (typeof(objects[key]) === 'object') getIdInObjects(id, objects[key], output); } return output; } console.log('items', [object1, object2])