Simran
Simran

Reputation: 633

How to append items to nested array in JavaScript

I have an outer JS array 'main_category' which should contain several arrays within it called 'temp'.

The array temp contains several string elements taken from an li tag.

In order to populate both the arrays I am running a for-loop through each li tag for each ul tag in the html page, as shown below:

function a{
   var category_list = [];
   var temp;

   //how to split this list iteration into two for-loops
   $(".ul_list li").each(function(){
       temp = [];
       //adding only those list elements of a ul, that are red in color
       if($(this).attr("style") == "color:red"){
          var cat = $(this).text();
          cat = cat.replace(/\s\s+/g, ' '); //removes whitespaces
          temp.push(cat); //creates a single array for a single element
       }
    }
    category_list.push(temp);  
   });
 }

Desired output:

  category_list = [['l1', 'l2', 'l3'], ['l1', 'l2', 'l3'], ['l1', 'l2', 'l3']..]

Current output:

   category_list = [['li'], ['l2'], ['l3']...]

However, the temp.push(cat) LOC creates a temp array for each individual li element instead of creating a temp=[] for all the li elements within one ul.

Upvotes: 1

Views: 1642

Answers (4)

halfer
halfer

Reputation: 20440

(Posted the solution on behalf of the question author).

This solution was provided by James_F:

   function a{
     let category_list = [];

     $(".ul_list").each(function(){
       let temp = [];
       $(this).children().each(function(){
          //adding only those list elements of a ul, that are red in color
          if($(this).children().attr("style") == "color:red"){
             var cat = $(this).text();
             cat = cat.replace(/\s\s+/g, ' '); //removes whitespaces
             temp.push(cat); //creates a single array for a single element
          }
       })
       category_list.push(temp);
     })
   }

Upvotes: 0

James_F
James_F

Reputation: 449

You can do this through iterating through each .ul_list element then their children in that order should give you the expected result.

function a() {
	let list = []
	$(".ul_list").each(function() {
		let temp = []
		$(this).children().each(function() {
			let text = $(this).text()
			text.replace(/\s\s+/g, ' ')
			temp.push(text)
		})
		list.push(temp)
	})
	return list
}

console.log(a())

Or if you need a recursive implementation that can handle nested uls inside of each other:

function getListItems(ul) {
  let temp = []
  $(ul).children().each(function() {
    if ($(this).is("ul")) { // checks if child is a list 
      temp.push(getListItems($(this))) // recursive call
    } else { // child is list item
      let text = $(this).text()
      text.replace(/\s\s+/g, ' ')
      temp.push(text)
    }
  })
  return temp
}


function a() { // main function
  let list = []
  $(".ul_list").each(function() {
    list.push(getListItems($(this)))
  })
  return list
}

console.log(a())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>

<head>
  <title></title>
  <link rel="stylesheet" type="text/css" href="style.css">
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
  <script src=https://code.jquery.com/jquery-1.9.1.js></script>
</head>

<body>
  <ul class="ul_list">
    <li>l1</li>
    <li>l2</li>
    <li>l3</li>
    <ul>
      <li>l1</li>
      <li>l2</li>
      <li>l3</li>
      <ul>
        <li>l1</li>
        <li>l2</li>
        <li>l3</li>
        <ul>
          <li>l1</li>
          <li>l2</li>
          <li>l3</li>
        </ul>
      </ul>
    </ul>
  </ul>
  <ul class="ul_list">
    <li>l1</li>
    <li>l2</li>
    <li>l3</li>
    <ul>
      <li>l1</li>
      <li>l2</li>
      <li>l3</li>
      <ul>
        <li>l1</li>
        <li>l2</li>
        <li>l3</li>
        <ul>
          <li>l1</li>
          <li>l2</li>
          <li>l3</li>
          <ul>
            <li>l1</li>
            <li>l2</li>
            <li>l3</li>
          </ul>
        </ul>
      </ul>
    </ul>
  </ul>
  <ul class="ul_list">
    <li>l1</li>
    <li>l2</li>
    <li>l3</li>
  </ul>
  <ul class="ul_list">
    <li>l1</li>
    <li>l2</li>
    <li>l3</li>
  </ul>
  <ul class="ul_list">
    <li>l1</li>
    <li>l2</li>
    <li>l3</li>
  </ul>
  <script type="text/javascript" src="main.js"></script>
</body>

</html>

Upvotes: 2

Vladimir Mujakovic
Vladimir Mujakovic

Reputation: 680

Maybe a bit over simplified but I got the desired output.
https://jsbin.com/tofimik/edit?html,js,console,output

Step 1. declare empty array
Step 2. run your loop, get all children in your ul element
Step 3. Turn each collection of children into an array
Step 4. Push child collection into new array

  var temp = []
  var cat;
  $('ul').each(function(){
    cat = []
    var liTags = Array($(this).children().text().trim());
    temp.push(liTags);
  })

Upvotes: 0

Taplar
Taplar

Reputation: 24965

The following will map each ul to an array, and all the lis in each ul to an array, so it will be a 2 dimensional array, where each category_list[#] is a ul and the sub array is each li's text you modified.

function a() {
  var category_list = $('.ul_list').get().map(function(ul){
    return $('li', ul).get().map(function(li){
      return $(li).text().replace(/\s\s+/g, ' '); //removes whitespaces
    });
  });
  
  console.log(category_list);
}

a();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<ul class="ul_list">
  <li>1 Thing</li>
  <li>2 Thing</li>
  <li>3 Thing</li>
</ul>

<ul class="ul_list">
  <li>4 Thing</li>
  <li>5 Thing</li>
  <li>6 Thing</li>
</ul>

Upvotes: 0

Related Questions