Skip to content
Advertisement

Function to create multidimensional object

Hello I’m strugglling with write everything from multi depth ul list into one object. I’ve got something like this.

  • Depth One 1
    • Depth Two 1
      • Depth Three 1
      • Depth Three 1
    • Depth Two 1
  • Depth One 2
    • Depth Two 2
      • Depth Three 2
    • Depth Two 2
      • Depth Three 2
      • Depth Three 2
      • Depth Three 2
  • Depth One 3
    • Depth Two 3
      • Depth Three 3
      • Depth Three 3
      • Depth Three 3
      • Depth Three 3
      • Depth Three 3
      • Depth Three 3
      • Depth Three 3
    • Depth Two 3

And i want to create one object with values from it. I want to make it like

const object = {
0:{
  item : Depth One 1,
  length: length of Depth Two,
  values:{
           0:{
           item: Depth One 1 => Depth Two 1(1st item)
           length: length: length of Depth Three,
           values:{
                   0:{
                      item: Depth One 1 => Depth Two 1 => Depth Three 1(1st item)
                      }
                   1:{
                      item: Depth One 1 => Depth Two 1 => Depth Three 1(2nd item)
                      }
          }
  }
  }
}
}

I’ve tried to do it with 3 for loops, but I didn’t get the result that I wanted. Thanks for all answers!

My code:

export function object(li, li2, li3, heightOfLi, widthOfLi) {
  let obj = {};

  for (let i = 0; i < li.length; i++) {
    let obj2 = {};
    if (li2[i] == undefined) {
      continue;
    }
    let counter = li2[i].querySelectorAll(".li-depth-2");
    if (counter == null) {
      continue;
    }

    for (let j = 0; j < counter.length; j++) {
      let obj3 = {};
      let counter2 = li3[j].querySelectorAll(".li-depth-3");

      if (counter2 == null) {
        continue;
      }

      for (let k = 0; k < counter2.length; k++) {
        obj3[k] = {
          name: li3[j].querySelectorAll(".li-depth-3 span")[k].textContent,
          item: li3[j].querySelectorAll(".li-depth-3")[k],
        };

        obj2[j] = {
          name: li2[i].querySelectorAll(".li-depth-2 span")[j].textContent,
          item: li2[i].querySelectorAll(".li-depth-2")[j],
          values: obj3,
        };
      }
    }

    obj[i] = {
      name: li[i].querySelector("span").innerText,
      item: li[i],
      length: counter.length,
      values: obj2,
    };
  }
  return obj;
}

Advertisement

Answer

I’m not sure about your markup, but I assumed a markup based on your example as below.

Few points before getting to solution:

  • To solve the problem, I would rather use reduce than for loop. Which is more convenient.
  • The algorithm gets the needed elements using querySelector and querySelectorAll and generates the desired object by reducing the array of elements into an object
  • Writing a generic function to generate an object for level and calling it recursively is neater and easier to scale.
  • It’s more convenient in JavaScript to generate arrays of arrays rather than object of objects. And that’s what I did. But you can convert the array into an object easily by using {...array} spread operator.
  • Finally the desired object is not clear enough but I think you would get the general idea with the result array down below in the snippet.

function getChildren(container, ...levels) {
  const parent = container.querySelector(levels[0])
  const elements = container.querySelectorAll(levels[0])

  return [...elements].reduce((acc, cur) => {
    const children = cur.querySelectorAll(levels[1])
    return [...acc, {
      item: cur.querySelector("span").innerText,
      length: [...children].length,
      values: getChildren(parent, levels[1], levels[2], null)
    }]
  }, [])
}

console.log(getChildren(document, ".depth-one", ".depth-two", ".depth-three"))
<ul>
  <li class="depth-one">
    <span>Depth One 1</span>
    <ul>
      <li class="depth-two"><span>Depth Two 1<span>
        <ul>
          <li class="depth-three"><span>Depth Three 1<span></li>
          <li class="depth-three"><span>Depth Three 1</span></li>
    </ul>
  </li>
  <li class="depth-two"><span>Depth Two 1</span></li>
</ul>
</li>
<li class="depth-one"><span>Depth One 2</span>
  <ul>
    <li class="depth-two"><span>Depth Two 2</span>
      <ul>
        <li class="depth-three"><span>Depth Three 2</span></li>
      </ul>
    </li>
    <li class="depth-two"><span>Depth Two 2</span>
      <ul>
        <li class="depth-three"><span>Depth Three 2</span></li>
        <li class="depth-three"><span>Depth Three 2</span></li>
        <li class="depth-three"><span>Depth Three 2</span></li>
      </ul>
    </li>
  </ul>
</li>
<li class="depth-one"><span>Depth One 3</span>
  <ul>
    <li class="depth-two"><span>Depth Two 3</span>
      <ul>
        <li class="depth-three"><span>Depth Three 3</span></li>
        <li class="depth-three"><span>Depth Three 3</span></li>
        <li class="depth-three"><span>Depth Three 3</span></li>
        <li class="depth-three"><span>Depth Three 3</span></li>
        <li class="depth-three"><span>Depth Three 3</span></li>
        <li class="depth-three"><span>Depth Three 3</span></li>
        <li class="depth-three"><span>Depth Three 3</span></li>
      </ul>
    </li>
    <li class="depth-two"><span>Depth Two 3</span></li>
  </ul>
</li>
</ul>
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement