0

I have the following array tree in javascript:

[
  {
    "id": 1,
    "parentId": null,
    "description": "Item 1",
    "value": 0,
    "children": [
      {
        "id": 2,
        "parentId": 1,
        "description": "Item 1.1",
        "value": 0,
        "children": [
          {
            "id": 3,
            "parentId": 2,
            "description": "Item 1.1.1",
            "value": 0,
            "children": []
          }
        ]
      }
    ]
  },
  {
    "id": 4,
    "parentId": null,
    "description": "Item 2",
    "value": 0,
    "children": [
      {
        "id":5,
        "parentId": 4,
        "description": "Item 2.1",
        "value": 0,
        "children": []
      }
    ]
  }
]

I want to turn it into a flat one with it's levels, like this (see level attribute):

[
  {
    "id":1,
    "parentId": null,
    "description":"Item 1",
    "value":0,
    "level": "1"
  },
  {
    "id":2,
    "parentId": 1,
    "description":"Item 1.1",
    "value":0,
    "level": "1.1"
  },
  {
    "id":3,
    "parentId": 2,
    "description":"Item 1.1.1",
    "value":0,
    "level": "1.1.1"
  },
  {
    "id":4,
    "parentId": null,
    "description":"Item 2",
    "value":0,
    "level": "2"
  },
  {
    "id":5,
    "parentId": 4,
    "description":"Item 2.1",
    "value":0,
    "level": "2.1"
  }
]

What's the best way to do this regardless of depth?

PS: I have the flat one too, but without "level" attribute and the proposal is to add this attribute based on parentId and sort list by it, like following:

Item 1
Item 1.1
Item 1.1.1
Item 2
Item 2.1

2 Answers 2

1

If you don't want to limit the solution by the depth of the array, then I suggest not to use recursion.

const solution = data => {
  const stack = data.map((item, index) => ({ ...item, level: `${index + 1}` }))
  const result = []
  
  while (stack.length) {
    const item = stack.pop()
    
    const { children, ...restItem } = item
    
    stack.push(...item.children.map((child, index) => ({ ...child, level: `${item.level}.${index + 1}` })))
    
    result.push(restItem)
  }
  
  return result
}

const data = [
  {
    "id": 1,
    "parentId": null,
    "description": "Item 1",
    "value": 0,
    "children": [
      {
        "id": 2,
        "parentId": 1,
        "description": "Item 1.1",
        "value": 0,
        "children": [
          {
            "id": 3,
            "parentId": 2,
            "description": "Item 1.1.1",
            "value": 0,
            "children": []
          }
        ]
      }
    ]
  },
  {
    "id": 4,
    "parentId": null,
    "description": "Item 2",
    "value": 0,
    "children": [
      {
        "id":5,
        "parentId": 4,
        "description": "Item 2.1",
        "value": 0,
        "children": []
      }
    ]
  }
]

console.log(solution(data))

Sign up to request clarification or add additional context in comments.

3 Comments

@larz check again please, there are no nested objects and it has level attribute with correct value
lol please disregard my previous comment. That's what I get for trying to multitask :)
yeah, it's happens :)
0

If you recursively loop through your array (assuming that children will always be the key), something like this will work.

const arr = [
  {
    "id": 1,
    "parentId": null,
    "description": "Item 1",
    "value": 0,
    "children": [
      {
        "id": 2,
        "parentId": 1,
        "description": "Item 1.1",
        "value": 0,
        "children": [
          {
            "id": 3,
            "parentId": 2,
            "description": "Item 1.1.1",
            "value": 0,
            "children": []
          }
        ]
      }
    ]
  },
  {
    "id": 4,
    "parentId": null,
    "description": "Item 2",
    "value": 0,
    "children": [
      {
        "id":5,
        "parentId": 4,
        "description": "Item 2.1",
        "value": 0,
        "children": []
      }
    ]
  }
]

const newArray = [];

const flatten = (item, parentIdx) => {
  // separate parent from children
  item.forEach(({ children, ...child}, idx) => {
    // create level
    const level = `${parentIdx ? `${parentIdx}.` : ''}${idx + 1}`;
    // add parent to new array
    newArray.push({...child, level});
    // recursively flatten children
    flatten(children, level);
  })
}

flatten(arr)

console.log(newArray)

1 Comment

I'm not sure if this is required, but with such a solution it will not be possible to solve the problem for 3000 or more nested elements

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.