создание вложенного несортированного списка из массива javascript - PullRequest
0 голосов
/ 23 февраля 2019

Я изо всех сил пытаюсь выяснить, как создать вложенный несортированный список из предопределенного массива JavaScript.Массив выглядит так:

var directory = [
  { type: 'file', name: 'file1.txt' },
  { type: 'file', name: 'file2.txt' },
  {
    type: 'directory',
    name: 'HTML Files',
    files: [
      { type: 'file', name: 'file1.html' },
      { type: 'file', name: 'file2.html' }
    ]
  },
  { type: 'file', name: 'file3.txt' },
  {
    type: 'directory',
    name: 'JavaScript Files',
    files: [
      { type: 'file', name: 'file1.js' },
      { type: 'file', name: 'file2.js' },
      { type: 'file', name: 'file3.js' }
    ]
  }
];

И вывод, который я получаю, равен

<ul>
  <li>file1</li>
  <li>file2</li>
  <li>HTML files:
    <ul>
      <li>file1</li>
      <li>file2</li>
    </ul>
  </li>
  <li>
    file3
  </li>
  <li>JavaScript Files:
    <ul>
      <li>file1</li>
      <li>file2</li>
      <li>file3</li>
    </ul>
</ul>

Ответы [ 3 ]

0 голосов
/ 23 февраля 2019

Вы можете создать рекурсивную функцию для обхода каталога.

<!doctype html>
<html>
  <body>

  </body>
  <script>
var directory = [
  { type: 'file', name: 'file1.txt' },
  { type: 'file', name: 'file2.txt' },
  {
    type: 'directory',
    name: 'HTML Files',
    files: [
      { type: 'file', name: 'file1.html' },
      { type: 'file', name: 'file2.html' }
    ]
  },
  { type: 'file', name: 'file3.txt' },
  {
    type: 'directory',
    name: 'JavaScript Files',
    files: [
      { type: 'file', name: 'file1.js' },
      { type: 'file', name: 'file2.js' },
      { type: 'file', name: 'file3.js' }
    ]
  }
];

function generateList(fdList) {
  let mainUl = document.createElement("UL");
  for (let i = 0; i < fdList.length; ++i) {
    let newLi = document.createElement("LI");
    let fd = fdList[i];
    let textNode = null;
    let fdName = null;
    if (fd.type === 'file') {
      fdName = fd.name.split('.').splice(0, 1)[0];
      textNode = document.createTextNode(fdName);
      newLi.appendChild(textNode);
    } else {
      textNode = document.createTextNode(fd.name);
      newLi.appendChild(textNode);
      newLi.appendChild(generateList(fd.files));
    }
    mainUl.appendChild(newLi);
  }
  return mainUl;
}

document.body.appendChild(generateList(directory));
  </script>
</html>
0 голосов
/ 25 февраля 2019

Я знаю, что ответы уже есть, но вот забавное решение с использованием Array.map и шаблонов.Он также рекурсивен и поэтому может обрабатывать глубину n.

var directory = [
  { type: 'file', name: 'file1.txt' },
  { type: 'file', name: 'file2.txt' },
  {
    type: 'directory',
    name: 'HTML Files',
    files: [
      { type: 'file', name: 'file1.html' },
      { type: 'file', name: 'file2.html' }
    ]
  },
  { type: 'file', name: 'file3.txt' },
  {
    type: 'directory',
    name: 'JavaScript Files',
    files: [
      { type: 'file', name: 'file1.js' },
      { type: 'file', name: 'file2.js' },
      { type: 'file', name: 'file3.js' }
    ]
  }
];

const getName = (fileName) => fileName.split('.')[0];
const renderFile = (file) => `<li>${getName(file.name)}</li>`;
const renderDirectory = (data) => data.map(item => (item.type === 'file') ? renderFile(item) : `<li>${item.name}:<ul>${renderDirectory(item.files)}</ul></li>`).join('');

document.addEventListener('DOMContentLoaded', () => {
  let ul = document.createElement('ul');
  ul.innerHTML = renderDirectory(directory);
  document.querySelector('#target').appendChild(ul);
});
<div id="target"></div>
0 голосов
/ 23 февраля 2019

Вы можете использовать несколько forEach, как показано ниже:

var list = [];
var listItem;
var directory = [
  { type: 'file', name: 'file1.txt' },
  { type: 'file', name: 'file2.txt' },
  {
    type: 'directory',
    name: 'HTML Files',
    files: [
      { type: 'file', name: 'file1.html' },
      { type: 'file', name: 'file2.html' }
    ]
  },
  { type: 'file', name: 'file3.txt' },
  {
    type: 'directory',
    name: 'JavaScript Files',
    files: [
      { type: 'file', name: 'file1.js' },
      { type: 'file', name: 'file2.js' },
      { type: 'file', name: 'file3.js' }
    ]
  }
];

directory.forEach(element => {
  if (element.type == "file") {
    listItem = "<li>" + element.name.match(/[^.]*/) + "</li>";
    list.push(listItem);
  }
  else if (element.type == "directory") {
    listItem = "<li>" + element.name + "<ul>";
    element.files.forEach(e => {
      listItem += "<li>" + e.name.match(/[^.]*/) + "</li>";
    });
    listItem += "</ul></li>"
    list.push(listItem);
  }
});

document.getElementById("list").innerHTML = list.join('');
<h2>Expected Result</h2>
<ul style="background: orange;">
  <li>file1</li>
  <li>file2</li>
  <li>HTML files:
    <ul>
      <li>file1</li>
      <li>file2</li>
    </ul>
  </li>
  <li>
    file3
  </li>
  <li>JavaScript Files:
    <ul>
      <li>file1</li>
      <li>file2</li>
      <li>file3</li>
    </ul>
</ul>

<h2>Output</h2>
<ul id="list" style="background: yellow"></ul>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...