J'ai un tableau avec des objets, qui peuvent avoir des enfants, les enfants ont la même structure que le parent, c'est juste une imbrication d'objets en gros.
Je me demande comment je peux aplatir la structure de mes objets donc j'ai les identifiants de tous les objets, y compris celui imbriqué.
Par exemple, Cette structure
const data = [2,1,3]
Doit être aplatie à ceci
const data = [ { id: 2, children: [ { id: 1, children: [] } ] }, { id: 3, children: [], } ]
En utilisant Array.reduce () et la syntaxe de propagation d'objets, mais je ne peux pas comprendre la logique nécessaire pour ce faire.
9 Réponses :
Vous pouvez utiliser JSON.stringify
, et pour chaque clé de id
, pousser vers un tableau:
const data = [ { id: 2, children: [ { id: 1, children: [] } ] }, { id: 3, children: [], } ] const ids = []; JSON.stringify(data, (key, val) => { if (key === 'id') { ids.push(val); } return val; }); console.log(ids);
Ohhh - Cool. Je n'avais aucune idée que stringify prenait des paramètres. J'ai aussi utilisé stringify puis une regex
Curieusement, cela ne se répète pas: JSON.stringify (data, ["id"])
C'est un travail de récursivité. Faites une boucle sur le tableau et pour chaque élément qu'il contient, insérez l'identifiant dans un nouveau tableau et répétez pour les enfants.
const data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [], } ]; console.log(flatten(data)); function flatten(data) { const result = []; recursive(data); return result; function recursive(data) { data.forEach(member => { result.push(member.id); recursive(member.children); }); } }
Vous pouvez utiliser une approche récursive.
const data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [], } ]; function flatArr(arr, res) { // iterate over the array arr.forEach(o => { // check id is present then push it into the result array if ('id' in o) res.push(o.id) // check children is present and non-empty // then ecursively call the function if (o.children && o.children.length) flatArr(o.children, res); }) // return the result array(optional since it's the same array reference you are passing initially) return res; } console.log(flatArr(data, []));
function flatArr(arr, res) { // iterate over the array arr.forEach(o => { // check id is present then push it into the result array if ('id' in o) res.push(o.id) // check children is present and non-empty // then ecursively call the function if (o.children && o.children.length) flatArr(o.children, res); }) // return the result array(optional) return res; } console.log(flatArr(data, []));
Vous pouvez réduire le tableau des objets en utilisant l'ID réel et obtenir leurs objets enfants.
const getId = array => array.reduce( (r, { id, children }) => [...r, id, ...getId(children)], [] ), data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [] }], ids = getId(data); console.log(ids);
Vous pouvez utiliser une approche récursive et itérer pour chaque enfants
et pousser tous les id
dans un tableau.
const data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [], } ], getId = (data) => data.reduce((r,{id, children}) => r.concat(id, getId(children)),[]); console.log(getId(data));
const data = [ { id: 2, children: [ { id: 1, children: [] } ] }, { id: 3, children: [], } ] const getIds = (data) => data.map(d => [d.id, ...getIds(d.children)]).flat() console.log(getIds(data))
C'est élégant
J'ai accepté cette réponse, comme la ligne! Merci
Vous pouvez utiliser la récursivité.Notez que ci-dessous la référence de code de arr
est passée afin que nous puissions directement pousser ()
les identifiants dessus et pas besoin d'obtenir renvoie
valeur
const data = [{ id: 2, children: [{ id: 1, children: [] }] }, { id: 3, children: [], } ] function getIds(data,arr){ //iterate over array of chilren for(let child of data){ //add id of each child to arr arr.push(child.id); //check if child have children add its 'ids' to same array if(child.children) getIds(child.children,arr); } //return array in end return arr; } console.log(getIds(data,[]))
Je n'aime pas les récursions :)
Notez l'autre réponse Stringify - ILST
https://stackoverflow.com/a/55179326/295783
const data=[{id:2,children:[{id:1,children:[]}]},{id:3,children:[],}]; console.log( JSON.stringify(data) .match(/(?:"id":)(\d+)/g) .map(v => +v.replace(/"id":/g, "")) )
Je souhaite cependant que quelqu'un puisse me trouver un moyen d'ignorer le groupe non capturant en une seule fois
Convertissez chaque valeur en Number
. Solution vraiment étrange +1
@MaheerAli Terminé;)
Une autre version. Pas le plus joli mais fait le travail:
const data = [ { id: 2, children: [ { id: 1, children: [] } ] }, { id: 3, children: [], } ]; let mappedArray = data.map(num => [].concat(num.children.map(child => child.id)).concat(num.id)); mappedArray = [].concat.apply([], mappedArray); console.log(mappedArray);