J'ai un arbre comme:
let array = [
{"id":1},
{"id":2},
{"id":3},
{"id":4},
{"id":5},
{"id":6},
]
Comment analyser cet arbre pour pousser chaque nœud à l'intérieur des enfants dans un nouveau tableau? Je suppose que je dois l'analyser récursivement. Pouvez-vous m'aider s'il vous plaît?
Le résultat devrait être comme:
{
"nodes": [
{
"id":1,
"children":[
{
"id":3,
"children":[
{"id":4, "children":[]},
{"id":5, "children":[{"id":6, "children":[]}]}
]
},
{"id":2, "children":[]}
]
}
]
}
8 Réponses :
Vous pouvez adopter une approche itérative et récursive. Si vous souhaitez obtenir un résultat ordonné, vous pouvez ajouter un tri.
.as-console-wrapper { max-height: 100% !important; top: 0; }
function getValues(array) {
return array.reduce((r, { id, children }) => [...r, { id }, ...getValues(children)], []);
}
var data = { nodes: [{ id: 1, children: [{ id: 3, children: [{ id: 4, children: [] }, { id: 5, children: [{ id: 6, children: [] }] }] }, { id: 2, children: [] }] }] };
console.log(getValues(data.nodes));
Une solution récursive est la voie à suivre:
snip-css
const data = {"nodes":[{"id":1,"children":[{"id":3,"children":[{"id":4,"children":[]},{"id":5,"children":[{"id":6,"children":[]}]}]},{"id":2,"children":[]}]}]};
const getChildren = obj => {
let result = [];
obj.children.forEach(child => {
if (child.children && child.children.length) {
result.push({ id: child.id });
result = result.concat(getChildren(child));
} else {
result.push({ id: child.id });
}
});
return result;
};
let res = data.nodes.flatMap(getChildren);
console.log(res);
Vous pouvez créer votre propre fonction d'analyse en utilisant la méthode reduction pour renvoyer tous les nœuds enfants dans une structure de tableau plat.
const tree = {"nodes":[{"id":1,"children":[{"id":3,"children":[{"id":4,"children":[]},{"id":5,"children":[{"id":6,"children":[]}]}]},{"id":2,"children":[]}]}]}
function parse(arr) {
return arr.reduce((r, e) => {
const {children, ...rest} = e;
r.push(rest)
const childNodes = parse(children);
if (childNodes.length) r.push(...childNodes);
return r;
}, [])
}
const data = parse(tree.nodes);
console.log(data)
Vous pouvez utiliser une fonction pour itérer objet par propriété comme ci-dessous
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="output"></div>
var object = {
"nodes": [
{
"id":1,
"children":[
{
"id":3,
"children":[
{"id":4, "children":[]},
{"id":5, "children":[{"id":6, "children":[]}]}
]
},
{"id":2, "children":[]}
]
}
]
}
var result = [];
function iterate(obj, stack) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property], stack + '.' + property);
} else {
//console.log(property + " " + obj[property]);
result.push({[property]: obj[property]});
//$('#output').append($("<div/>").text(stack + '.' + property))
}
}
}
}
iterate(object, 'id');
console.log(result)
Une solution récursive de base serait:
var tree = {
"nodes": [
{
"id":1,
"children":[
{
"id":3,
"children":[
{"id":4, "children":[]},
{"id":5, "children":[{"id":6, "children":[]}]}
]
},
{"id":2, "children":[]}
]
}
]
}
function parse(tree, current) {
if (current === undefined || current === null) {
current = [];
}
if (Array.isArray(tree)) {
tree.forEach(function (node) {
if (node.id !== undefined) {
current = current.concat([{ id: node.id }]);
}
if (node.children !== undefined) {
current = parse(node.children, current);
}
});
}
return current;
}
console.log(parse(tree.nodes));
Vous pouvez utiliser une fonction récursive comme ci-dessous:
var nodeObject = {
"nodes": [{
"id": 1,
"children": [{
"id": 3,
"children": [{
"id": 4,
"children": []
},
{
"id": 5,
"children": [{
"id": 6,
"children": []
}]
}
]
},
{
"id": 2,
"children": []
}
]
}]
}
var ids = [];
function getIds(node) {
ids.push({
id: node.id
});
if (node.children && node.children.length > 0) {
node.children.forEach(childNode => getIds(childNode))
}
}
nodeObject.nodes.forEach(node => getIds(node))
console.log(ids);
Récursivité simple:
data = {
"nodes": [
{
"id":1,
"children":[
{
"id":3,
"children":[
{"id":4, "children":[]},
{"id":5, "children":[{"id":6, "children":[]}]}
]
},
{"id":2, "children":[]}
]
}
]
}
var ids = [];
function getIdsFromArray(children) {
children.forEach((item) => {
if (item.id)
ids.push({"id": item.id});
if (item.children && Array.isArray(item.children))
getIdsFromArray(item.children)
})
}
getIdsFromArray(data.nodes);
console.log(ids)
//# sourceURL=snippet:///test
Il y a plusieurs façons de faire cela, l'une d'elles est ma solution. Je suis sûr que vous trouverez un meilleur moyen - mais j'ai trouvé la technique Object.entries assez facile.
const myObj = {
"nodes": [
{
"id":1,
"children":[
{
"id":3,
"children":[
{"id":4, "children":[]},
{"id":5, "children":[{"id":6, "children":[]}]}
]
},
{"id":2, "children":[]}
]
}
]
}
let noteArray = Object.entries(myObj.nodes);
let pushArray = [];
for(const [noteKey, noteValue] of noteArray) {
pushArray.push({"id": noteValue.id});
for(const [childKey, childValue] of Object.entries(noteValue.children)) {
pushArray.push({"id": childValue.id});
for(const [child2Key, child2Value] of Object.entries(childValue.children)) {
pushArray.push({"id": child2Value.id});
}
}
}
console.log(pushArray);
Quelle devrait être la sortie?
Qu'as-tu essayé?