0

I'm searching for a little help/advice. I had a task to create a multiple nested list from array of object. I did this, got a expected result, but the problem was my code was very complicated and not clean for sure, because i did it by mapping, filtering, and again mapping, mapped arrays. This give me a lot of code, and i am pretty sure you can do it a lot of easier, that's why i am searching for help. I am using react(18.2.0), but even good methods for situations like that in vanilla js will be very helpful for me.

So I have a JSON file with a lot of data, I give a example because there is like Array[500+] object inside.

"data": [
        {
            "categoryId": 1,
            "name": "Football",
            "lvl": 1,
            "parent": 0,
        },
        {
            "categoryId": 2,
            "name": "Basketball",
            "lvl": 1,
            "parent": 0,
        },
        {
            "categoryId": 3,
            "name": "Bundesliga",
            "lvl": 2,
            "parent": 1,
        },
        {
            "categoryId": 4,
            "name": "NBA",
            "lvl": 2,
            "parent": 2,
        },
        {
            "categoryId": 5,
            "name": "Wizards",
            "lvl": 3,
            "parent": 4,
        },
        {
            "categoryId": 6,
            "name": "Lakers",
            "lvl": 3,
            "parent": 4,
        },

.....and more

If parent === categoryId it means that it's children.

So the result component should give something like that:

 - Football
      - Bundesliga
    - Basketball
      - NBA
        - Wizards
        - Lakers

I will be happy if you give me some good practices, advice about situations like that. Should I use recursion or what? :)

1 Answer 1

1

If you wanted to write this recursively, you could write it something like this:

const recursive = function(data, node, current, max) {
  if(current > max) {
    return {};
  }
  data.forEach( d => {
    if(!node.children) {
      node.children = [];
    }
    if(d.lvl === current && (d.parent === node.categoryId || current === 1)) {
      node.children.push(d);
      recursive(data, d, current+1, max)
    }
  });
}

let newObj = {};
let highestLevel = 1;
data.forEach(d => {
  if(d.lvl > highestLevel) {
    highestLevel = d.lvl;
  }
})
recursive(data, newObj, 1, highestLevel)

I wrote this in playcode.io so that you can see it working: https://playcode.io/926085

The output is the entire objects, nested. But you can then print just the names from the resulting nested structure.

I don't think that this solution is the most optimal one, as far as time complexity goes. But it's a recursive example of how to solve the problem.

I'm open to someone optimizing this solution, as I am also interested in this problem.

UPDATE

I had a friend work on a solution. He optimized so that I think its O(n): https://playcode.io/926145/

const f = (input, map = {}) => {
  input.forEach(d => {
    const me = map[d.categoryId]

    if(!me) {
      map = {...map, [d.categoryId]: [] }
    }

    const siblings = map[d.parent]
    if(siblings) {
      map = {...map, [d.parent]: [...siblings, d]}
    } else {
      map = {...map, [d.parent]: [d]}
    }
  })

  return map
}

const print = (map, input, toPrint, indent = 0) => {
  toPrint.forEach(p => {
    const ind = " ".repeat(indent)

    console.log(`${ind} - ${p.name}`)

    print(map, input, map[p.categoryId], indent + 2)
  })
}

const map = f(data.data)
print(map, data.data, map[0])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.