WedX - журнал о программировании и компьютерных науках

Генерация многомерного массива/объекта из вложенного списка html

Я хочу создать массив, представляющий структуру упорядоченного списка.

Список может быть примерно таким:

<ol class="list">
    <li><p>1</p>
        <ol>
            <li><p>1.1</p></li>
            <li><p>1.2</p></li>
            <li><p>1.3</p>
                <ol>
                    <li><p>1.3.1</p></li>
                </ol>
            </li>
            <li><p>1.4</p></li>
        </ol>
    </li>
    <li><p>2</p></li>
    <li><p>3</p></li>
</ol>

Я использую следующую функцию Javascript/Jquery для обхода этого списка (на основе этого ответа: https://stackoverflow.com/a/18084008/11995425 )

var count = 0;
var pages = [];
var parentStack = [];

var result = {};

parentStack.push(0);

function createNewLevel(obj) {
    var obj = obj || $('.list');

    if (obj.prop('tagName') == 'P') {
        ++count;

        pages.push({
            pId: parentStack[parentStack.length - 1],
            urlStr: obj.text(), myId: count
        });
    }

    if(obj.children().length > 0 ) {

        obj.find('> li').each(function(i){

            $(this).children().each(function(j){

                if($(this).prop('tagName') == 'OL') {
                    parentStack.push(count);
                }

                createNewLevel($(this));

                if($(this).prop('tagName') == 'OL') {
                    parentStack.pop();
                }
            });     
        })
    }
}
createNewLevel();

Это генерирует массив:

​0: Object { pId: 0, urlStr: "1", myId: 1 }
1: Object { pId: 1, urlStr: "1.1", myId: 2 }
2: Object { pId: 1, urlStr: "1.2", myId: 3 }
3: Object { pId: 1, urlStr: "1.3", myId: 4 }
4: Object { pId: 4, urlStr: "1.3.1", myId: 5 }
​5: Object { pId: 1, urlStr: "1.4", myId: 6 }
6: Object { pId: 0, urlStr: "2", myId: 7 }
7: Object { pId: 0, urlStr: "3", myId: 8 }

pId ссылается на myId как на родителя.

Я не могу преобразовать это в множественный массив. В конце я передаю этот массив (json.stringify) через ajax в PHP. В идеале этот массив должен быть сгенерирован во время выполнения "createNewLevel". Но также возможно впоследствии преобразовать его в PHP. Результат должен выглядеть так:

array(5) {
  [0]=>
  array(2) {
    ["desc"]=>
    string(1) "1"
    ["children"]=>
    array(0) {
    }
  }
  [1]=>
  array(2) {
    ["desc"]=>
    string(1) "2"
    ["children"]=>
    array(4) {
      [0]=>
      array(2) {
        ["desc"]=>
        string(3) "2.1"
        ["children"]=>
        array(0) {
        }
      }
      [1]=>
      array(2) {
        ["desc"]=>
        string(3) "2.2"
        ["children"]=>
        array(0) {
        }
      }
      [2]=>
      array(2) {
        ["desc"]=>
        string(3) "2.3"
        ["children"]=>
        array(3) {
          [0]=>
          array(2) {
            ["desc"]=>
            string(5) "2.3.1"
            ["children"]=>
            array(0) {
            }
          }
          [1]=>
          array(2) {
            ["desc"]=>
            string(5) "2.3.2"
            ["children"]=>
            array(0) {
            }
          }
          [2]=>
          array(2) {
            ["desc"]=>
            string(5) "2.3.3"
            ["children"]=>
            array(0) {
            }
          }
        }
      }
      [3]=>
      array(2) {
        ["desc"]=>
        string(3) "2.4"
        ["children"]=>
        array(0) {
        }
      }
    }
  }
  [2]=>
  array(2) {
    ["desc"]=>
    string(1) "3"
    ["children"]=>
    array(0) {
    }
  }
  [3]=>
  array(2) {
    ["desc"]=>
    string(1) "4"
    ["children"]=>
    array(0) {
    }
  }
  [4]=>
  array(2) {
    ["desc"]=>
    string(1) "5"
    ["children"]=>
    array(0) {
    }
  }
}
29.08.2019

Ответы:


1

Вы можете использовать метод reduce и рекурсию для создания вложенной структуры на основе вашего html. Если дочерний элемент имеет ol, вы вызываете функцию генерации, где параметром элемента будет этот элемент ol.

function generate(element, pid = 0) {
  return [...element.children].reduce((r, li) => {
    const p = li.querySelector('p');
    const ol = li.querySelector('ol');
    const obj = {pid};

    if (p) obj.text = p.textContent;
    if (ol) obj.children = generate(ol, pid + 1);

    r.push(obj);
    return r;
  }, [])
}

const result = generate(document.querySelector('.list'))
console.log(JSON.stringify(result, 0, 4))
<ol class="list">
    <li><p>1</p>
        <ol>
            <li><p>1.1</p></li>
            <li><p>1.2</p></li>
            <li><p>1.3</p>
                <ol>
                    <li><p>1.3.1</p></li>
                </ol>
            </li>
            <li><p>1.4</p></li>
        </ol>
    </li>
    <li><p>2</p></li>
    <li><p>3</p></li>
</ol>

29.08.2019
  • Отличный кусок js! Спасибо большое. 31.08.2019
  • @Loewe Я рад, что смог помочь. 31.08.2019
  • Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]