JavaScript: How to create an unordered list from an array?

I have the following array and I want to create an unordered list from it, but I had a problem creating an unordered list in the appropriate format. I was looking for similar questions, but none of the existing solutions work for my problem.

var myArray = ['Value 1', ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 'Value 2', 'Value 3', 'Value 4', 'Value 5', 'Value 6']; 

Here is my JavaScript code:

 function arrToUl(arr) { var div = document.getElementById('myList'); var ul = document.createElement('ul'); for (var i = 0; i < arr.length; i++) { if (arr[i] instanceof Array) { var list = arrToUl(arr[i]); } else { var li = document.createElement('li'); li.appendChild(document.createTextNode(arr[i])); console.log(ul.appendChild(li)); } div.appendChild(ul); } } arrToUl(myArray); 

The above code gives the following result:

 <ul> <li>Value 1</li> <li>Inner Value 1</li> <li>Inner Value 2</li> <li>Inner Value 3</li> <li>Inner Value 4</li> <li>Value 2</li> <li>Value 3</li> <li>Value 4</li > <li>Value 5</li > <li>Value 6</li> 

But the result should look like this:

 <ul> <li>Value 1 <ul> <li>Inner Value 1</li> <li>Inner Value 2</li> <li>Inner Value 3</li> <li>Inner Value 4</li> </ul> </li> <li>Value 2</li> <li>Value 3</li> <li>Value 4</li> <li>Value 5</li> <li>Value 6</li> 

Thank you for your help.

+5
source share
5 answers

You have added all the <ul> elements to myList <div> . To change this, I added a new parameter to the arrToUl(root, arr) function.

The new root parameter determines to whom the created <ul> should be added, so if the function encounters an auxiliary array, it uses the previous list item as the root to create the sub-list.

 var myArray = ['Value 1', ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 'Value 2', 'Value 3', 'Value 4', 'Value 5', 'Value 6']; function arrToUl(root, arr) { var ul = document.createElement('ul'); var li; root.appendChild(ul); // append the created ul to the root arr.forEach(function(item) { if (Array.isArray(item)) { // if it an array arrToUl(li, item); // call arrToUl with the li as the root return; } li = document.createElement('li'); // create a new list item li.appendChild(document.createTextNode(item)); // append the text to the li ul.appendChild(li); // append the list item to the ul }); } var div = document.getElementById('myList'); arrToUl(div, myArray); 
 <div id="myList"></div> 
+5
source

Your function is called arrToUl , so it should just do this: convert the array to ul .

After you have ul , you can paste it wherever you want, but do not do this outside the function.

Then everything becomes clear.

 function arrToUl(arr) { var ul = document.createElement('ul'), li; for (var i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) { li.appendChild(arrToUl(arr[i])); } else { li = document.createElement('li'); li.appendChild(document.createTextNode(arr[i])); ul.appendChild(li); } } return ul; } var myArray = ['Value 1', ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 'Value 2', 'Value 3', 'Value 4', 'Value 5', 'Value 6']; document.body.appendChild(arrToUl(myArray)); 
+1
source

You can save the last li and add an advanced function with the target DOM element to it.

 function iter(target) { var ul = document.createElement('ul'), li; target.appendChild(ul); return function (a) { if (Array.isArray(a)) { if (!li) { li = document.createElement('li'); ul.appendChild(li); } a.forEach(iter(li)); return; } li = document.createElement('li'); li.appendChild(document.createTextNode(a)); ul.appendChild(li); }; } var myArray = ['Value 1', ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 'Value 2', 'Value 3', 'Value 4', 'Value 5', 'Value 6']; myArray.forEach(iter(document.getElementById('myList'))); 
 <div id="myList"></div> 
0
source

Your recursive approach doesn't say anything about where it should add a new child. Maybe you should give, every time you get an array instance, the last element has a unique identifier. And then you can give this identifier to your parameters.

GUID Generator is a good way to make a unique identifier.

0
source

I would suggest a solution based on recursion that seems to me more clear and less error prone. It produces a slightly different result because it maps each element of the array to node at the same level, and I think this should be the result of creating ul from the array.

 var myArray = [ 'Value 1', ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4'], 'Value 2', 'Value 3', 'Value 4', 'Value 5', 'Value 6' ]; function appendItems(arr, el) { if(!arr.length) return el; else { var head = arr.shift(); var child = transform(head); var li = document.createElement('li'); li.appendChild(child); el.appendChild(li); return appendItems(arr, el); } } function transform(item) { if(Array.isArray(item)) { var ul = document.createElement('ul'); return appendItems(item, ul); } else { return document.createTextNode(item); } } var ul = transform(myArray); 

If you would like to have the mentioned output, it would be better to change the input format to fit one iteration per node. Example:

 var arr = [ {label: 'value1', subitems: ['Inner value 1', 'Inner value 2', 'Inner value 3', 'Inner value 4']} ]; 
0
source

Source: https://habr.com/ru/post/1261962/


All Articles