7

I have data like this:

var array = ["a", "b", "c", "d", "e"];

I want this data converted like this:

<ol>
 <li>a</li>
   <ol>
    <li>b</li>
     <ol>
      <li>c</li>
       <ol>
        <li>d</li>
       </ol>
     </ol>
  </ol>

I will try this:

var makeNestedList = () => {
  $.each(array, function(i, el) {
    nested += '<ol>';
    nested += '<li>' + el + '</li>';
    makeNestedList();
    nested += '</ol>';
  });
};

But why is the result empty?

4
  • 1
    maybe you should return nested variable from function. Commented Nov 15, 2017 at 14:04
  • Should it not be <ol> <li> <ol> <li></li> </ol> </li> </ol>? Commented Nov 15, 2017 at 14:05
  • The output should be: <ol><li>A</li><li><ol><li>B</li><li><ol><li>C</li><li><ol><li>D</li></ol></li></ol></li></ol></li></ol> Or thereabouts, as you need a list item to start a new ordered list within an existing list. Commented Nov 15, 2017 at 14:12
  • 1
    An <ol> should not directly contain another <ol>?! Commented Nov 15, 2017 at 16:55

4 Answers 4

13

You could use Array#reduceRight and create the most nested node first and then the outer ones.

var array = ["a", "b", "c", "d", "e"],
    result = array.reduceRight(function (r, a) {
        return '<ol><li>' + a + r + '</li></ol>';
    }, '');
    
document.body.innerHTML += result;
console.log(result);

From the outside to inside with nodes.

var array = ["a", "b", "c", "d", "e"];

array.reduce(function (node, item) {
    var ol = document.createElement('ol'),
        li = document.createElement('li');

    li.appendChild(document.createTextNode(item));
    ol.appendChild(li);
    node.appendChild(ol);
    return li;
}, document.body);

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

3 Comments

hmm, i recently understand, evidently method array.reduceRight, thanks thank you very much, and thank you about the new method,
Notice this creates invalid html. You should use something like (r && '<li>'+r+'</li>') instead
@Bergi, you are right, i moved the node inside of the <li> tag.
4

You have number of problems in your code. You need to pass input array into function and return something from it. Then you don't need loop inside, since you are using recursion anyway.

Something like this I think will fix it:

var array = ["a", "b", "c", "d", "e"];

var makeNestedList = (arr) => {
  let nested = '<ol>'
  nested += '<li>' + arr[0];
  if (arr.length > 1) {
    nested += makeNestedList(arr.slice(1));
  }
  nested += '</li></ol>';
  return nested
};

document.body.innerHTML = makeNestedList(array)

1 Comment

This is brilliant. You "loop" to your own function, from your function. I didn't know you could do that. I did add a <div id "myDiv"></div> in my HTML body part. I then inserted the list in it with: document.getElementById("myDiv").innerHTML = makeNestedList(array).
3

You can use something like this:

Logic

  • loop over array in reverse order.
  • For every item, create a ordered list.
  • Append this list to next list.

function createOrderedList(items) {
  var ol = document.createElement('ol');
  items.forEach(function(item){
    ol.appendChild(createListItem(item))
  })
  return ol;
}

function createListItem(item) {
  var li = document.createElement('li');
  li.textContent = item;
  return li;
}

var array = ["a", "b", "c", "d", "e"];

var list = array.reduceRight(function(p, c){
  var el = createOrderedList([c]);
  if(p === null) {
    p = el;
  }
  else {
    el.appendChild(p);
  }
  return el;
}, null);

document.querySelector('.content').appendChild(list);
<div class='content'/>

Comments

1

You can try following, your recursive is not correct.

var arr=[1,2,3];
var nested='';

 var nestIt=function(i){
    if(i==arr.length){
        return "";
    }
    nested += '<ol>';
    nested += '<li>' + arr[i]+ '</li>';
    nestIt(i+1)
    nested += '</ol>';

    return nested
}

nestIt(0);
nested;

it will display result in console.

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.