简体   繁体   中英

filter array of objects into tree of data

In my reducer, I am trying to filter an array of objects (categories), parent categories have parent: 0 , all other categories have a parent id. Categories are nested 3 deep max.

I would like to store the subcategories in an options array. I have this code below. I can't get any deep nested options, any ideas?

        // get top level categories
        const yearCategories = action.data.filter(
            category => category.parent == 0
        );

        const categorys = yearCategories.map(({ id, name: label }) => ({
            id,
            label,
            options: action.data
                .filter(({ parent }) => parent === id)
                .map(({ id, name: label }) => ({
                    id,
                    label,
                    options: action.data
                        .filter(({ subCategory }) => subCategory === id)
                        .map(({ id, name: label }) => ({ id, label }))
                }))
        }));

Sample json, from http://wordpress.rguc.co.uk/index.php/wp-json/tribe/events/v1/categories?per_page=60&page=1

      [
{"id":1,"parent":0,"description":"","name":"Year 3"}
{"id":2,"parent":0,"description":"","name":"Year 4"}
{"id":3,"parent":0,"description":"","name":"Year 5"}
{"id":4,"parent":1,"description":"","name":"Year 3 group"}
{"id":5,"parent":1,"description":"","name":"Year 3 group"}
{"id":6,"parent":2,"description":"","name":"Year 4 group"}
{"id":7,"parent":2,"description":"","name":"Year 4 group"}
{"id":8,"parent":3,"description":"","name":"Year 5 Group"}
{"id":9,"parent":3,"description":"","name":"Year 5 Group"}
{"id":10,"parent":4,"description":"","name":"Year 3 group student"}
{"id":11,"parent":4,"description":"","name":"Year 3 group student"}
{"id":12,"parent":5,"description":"","name":"Year 3 group student"}
{"id":13,"parent":5,"description":"","name":"Year 3 group student"}
{"id":14,"parent":6,"description":"","name":"Year 4 group student"}
{"id":15,"parent":6,"description":"","name":"Year 4 group student"}
]

Which I want to look like this, example for Year 3 :

{
  "id": 1,
    "name": "Year 3",
    "parent": 0,
  "options": [
    {
      "id": 4,
      "parent": 1,
      "name": "Year 3 group",
      "options": [
        {
          "id": 10,
          "parent": 4,
          "name": "Year 3 group student"
        },
        {
          "id": 11,
          "parent": 4,
          "name": "Year 3 group student"
        }
      ]
      },
    {
      "id": 5,
      "parent": 1,
      "name": "Year 3 group",
      "option":[]
    }
  ]}

You could take an object as reference to the nodes and an array for storing all nodes who have a parent property with zero, because this nodes vae no parent.

This solution works by iterating all nodes once and sortes beside the id as refernece of a node the parent as well. At the end all connected nodes are collected and in the right order.

This works for unsorted data, because of the object and the relation between nodes and their parents and parents and their childrens.

 var data = [{ id: 1, parent: 0, description: "", name: "Year 3" }, { id: 2, parent: 0, description: "", name: "Year 4" }, { id: 3, parent: 0, description: "", name: "Year 5" }, { id: 4, parent: 1, description: "", name: "Year 3 group" }, { id: 5, parent: 1, description: "", name: "Year 3 group" }, { id: 6, parent: 2, description: "", name: "Year 4 group" }, { id: 7, parent: 2, description: "", name: "Year 4 group" }, { id: 8, parent: 3, description: "", name: "Year 5 Group" }, { id: 9, parent: 3, description: "", name: "Year 5 Group" }, { id: 10, parent: 4, description: "", name: "Year 3 group student" }, { id: 11, parent: 4, description: "", name: "Year 3 group student" }, { id: 12, parent: 5, description: "", name: "Year 3 group student" }, { id: 13, parent: 5, description: "", name: "Year 3 group student" }, { id: 14, parent: 6, description: "", name: "Year 4 group student" }, { id: 15, parent: 6, description: "", name: "Year 4 group student" }], tree = function (data, root) { var r = [], o = {}; data.forEach(function (a) { a.options = o[a.id] && o[a.id].options; o[a.id] = a; if (a.parent === root) { r.push(a); } else { o[a.parent] = o[a.parent] || {}; o[a.parent].options = o[a.parent].options || []; o[a.parent].options.push(a); } }); return r; }(data, 0); console.log(tree); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM