2
votes

Générer un tableau plat d'ID à partir d'un arbre à plusieurs niveaux en utilisant la fonction de réduction avec récursivité?

J'essaie de mettre en œuvre une hiérarchie d'utilisateurs à l'aide de la bibliothèque js orgChart . par la méthode getHierarchy () dans la bibliothèque génère un objet comme celui-ci.

function getNestedArraysOfIds(node) {
    if (node.children == undefined) {
        return [node.id];
    } else {
        return [node.id,...node.children.map(subnode => (subnode.children==undefined) ? subnode.id: getNestedArraysOfIds(subnode))];
    }
}

function getIds(array) {
        return array.reduce((acc, subArray) =>
            (Array.isArray(subArray)) ? [...acc, ...getIds(subArray)] : [...acc, subArray]);
    }

var idArrays = getNestedArraysOfIds(datascource );
var ids = getIds(idArrays); //["1", "2", "3", "4", "5", "6", "7", "10", "12"]

Je veux générer un tableau plat à partir des identifiants de l'arborescence. ex: // ["1", "2", "3", "4", "5", "6", "7", "10", "12"] p>

J'ai trouvé,

var datascource = {
            "id": "1",
            "children": [{
                "id": "2"
            }, {
                "id": "3",
                "children": [{
                    "id": "4"
                }, {
                    "id": "5",
                    "children": [{
                        "id": "6"
                    }, {
                        "id": "7"
                    }]
                }]
            }, {
                "id": "10"
            }, {
                "id": "12"
            }]
        };

J'ai essayé de le faire avec une seule fonction de réduction mais je finis par écrire deux fonctions, toutes deux récursives. Existe-t-il un moyen élégant et efficace de le faire avec une seule fonction de réduction?

Merci d'avance.


3 Réponses :


2
votes

Utilisez une récursivité avec Array.flatMap () et répartir pour obtenir l'id et les identifiants des enfants, et aplatir en un seul tableau:

const getIds = ({ id, children }) => children ? [id, ...children.flatMap(getIds)] : id;

const dataSource = {"id":"1","children":[{"id":"2"},{"id":"3","children":[{"id":"4"},{"id":"5","children":[{"id":"6"},{"id":"7"}]}]},{"id":"10"},{"id":"12"}]};

const result = getIds(dataSource);

console.log(result);


0 commentaires

5
votes

Vous pouvez stabiliser les enfants en effectuant un mappage avec concat.

function getFlat({ id, children = [] }) {
    return children.reduce((r, o) => [...r, ...getFlat(o)], [id]);
}

var data = { id: "1", children: [{ id: "2" }, { id: "3", children: [{ id: "4" }, { id: "5", children: [{ id: "6" }, { id: "7" }] }] }, { id: "10" }, { id: "12" }] };

console.log(getFlat(data));

Idem avec une fonction de réduction

function getFlat({ id, children = [] }) {
    return [id].concat(...children.map(getFlat));
}

var data = { id: "1", children: [{ id: "2" }, { id: "3", children: [{ id: "4" }, { id: "5", children: [{ id: "6" }, { id: "7" }] }] }, { id: "10" }, { id: "12" }] };

console.log(getFlat(data));


0 commentaires

0
votes

Vous pouvez créer une simple fonction récursive et utiliser for..in pour l'itérer. Si la clé est id alors poussez sa valeur dans un tableau, sinon si la valeur de la clé est un tableau, par exemple la valeur de la clé children est un tableau , puis appelez la même fonction récursive dans une boucle for et passez chaque objet

let datascource = {
  "id": "1",
  "children": [{
    "id": "2"
  }, {
    "id": "3",
    "children": [{
      "id": "4"
    }, {
      "id": "5",
      "children": [{
        "id": "6"
      }, {
        "id": "7"
      }]
    }]
  }, {
    "id": "10"
  }, {
    "id": "12"
  }]
};

let data = [];

function flatData(obj) {
  for (let keys in obj) {
    if (keys === 'id') {
      data.push(obj[keys])
    } else if (Array.isArray(obj[keys])) {
      obj[keys].forEach((item) => {
        flatData(item)
      })

    }
  }
}
flatData(datascource)
console.log(data)


0 commentaires