1

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.

6
  • Are there multiple .ul_list? Also it looks like an invalid function definition for function a(){} Commented Apr 2, 2019 at 17:17
  • 1
    You push temp to the category array in a scope where temp is not defined. The expression category_list.push(temp) needs to be moved one line up. Commented Apr 2, 2019 at 17:17
  • @Taplar yes there are 12-15 .ul_list in the html template. No the function is being invoked successfully on the button click Commented Apr 2, 2019 at 17:20
  • The .ul_list li will select a flat list of <li> elements. The elements will not get magically grouped by their parent <ul> element. Commented Apr 2, 2019 at 17:26
  • Can you provide sample of input and desired output, as well as the output that you are actually getting? Commented Apr 2, 2019 at 18:04

4 Answers 4

2

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>

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

Comments

0

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>

4 Comments

This code is only creating an array with all li elements within it. It is not creating a sub-array for li elements belonging to one particular ul
The outer map is on the ul. The inner map is on the li's for the ul. You're saying this is not working? @Simran
Yes its creating a single Array(45) of 45 elements, i.e for a total of 5 list items * 9 lists
Weird, for some reason it was flattening it. Modified it, and included a runnable snippet to show it works.
0

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);
  })

Comments

0

(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);
     })
   }

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.