Как добавлять элементы во вложенный массив в JavaScript

#javascript #jquery #html

#javascript #jquery #HTML

Вопрос:

У меня есть внешний массив JS ‘main_category’, который должен содержать несколько массивов внутри него, называемых ‘temp’.

Массив temp содержит несколько строковых элементов, взятых из тега li.

Чтобы заполнить оба массива, я запускаю цикл for через каждый тег li для каждого тега ul на HTML-странице, как показано ниже:

 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(/ss /g, ' '); //removes whitespaces
          temp.push(cat); //creates a single array for a single element
       }
    }
    category_list.push(temp);  
   });
 }
  

Желаемый результат:

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

Текущий вывод:

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

Однако файл temp.push(cat) LOC создает временный массив для каждого отдельного элемента li вместо создания temp=[] для всех элементов li в пределах одного ul.

Комментарии:

1. Их несколько .ul_list ? Также это выглядит как недопустимое определение функции для function a(){}

2. Вы нажимаете temp на массив категорий в области, где temp не определено. Выражение category_list.push(temp) необходимо переместить на одну строку вверх.

3. @Taplar да, в шаблоне html есть 12-15 .ul_list. Нет, функция успешно вызывается при нажатии кнопки

4. .ul_list li Будет выбран плоский список <li> элементов. Элементы не будут волшебным образом сгруппированы по их родительскому <ul> элементу.

5. Можете ли вы предоставить образец ввода и желаемого результата, а также результат, который вы на самом деле получаете?

Ответ №1:

Вы можете сделать это путем перебора каждого .ul_list элемента, тогда их дочерние элементы в таком порядке должны дать вам ожидаемый результат.

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

console.log(a())  

Или, если вам нужна рекурсивная реализация, которая может обрабатывать вложенные ul элементы друг в друга:

 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(/ss /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>  

Ответ №2:

Следующее сопоставит каждый ul с массивом, а все li в каждом ul — с массивом, так что это будет 2-мерный массив, где каждый category_list[#] является ul, а вложенный массив — это текст каждого li, который вы изменили.

 function a() {
  var category_list = $('.ul_list').get().map(function(ul){
    return $('li', ul).get().map(function(li){
      return $(li).text().replace(/ss /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>  

Комментарии:

1. Этот код создает только массив со всеми элементами li внутри него. Это не создает подмассив для элементов li, принадлежащих одному конкретному ul

2. Внешняя карта находится на ul. Внутренняя карта находится на li для ul. Вы говорите, что это не работает? @Simran

3. Да, он создает один массив (45) из 45 элементов, то есть в общей сложности 5 элементов списка * 9 списков

4. Странно, по какой-то причине это сглаживало его. Изменил его и включил доступный для выполнения фрагмент, чтобы показать, что он работает.

Ответ №3:

Может быть, немного упрощено, но я получил желаемый результат.
https://jsbin.com/tofimik/edit?html ,js, консоль, вывод

Шаг 1. объявите пустой массив
Шаг 2. запустите свой цикл, получите все дочерние элементы в вашем ul элементе
Шаг 3. Превратите каждую дочернюю коллекцию в массив
Шаг 4. Поместите дочернюю коллекцию в новый массив

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

Ответ №4:

(Опубликовал решение от имени автора вопроса).

Это решение было предоставлено 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(/ss /g, ' '); //removes whitespaces
             temp.push(cat); //creates a single array for a single element
          }
       })
       category_list.push(temp);
     })
   }