仅获取数组及其子元素的一个

时间:2018-12-20 13:40:37

标签: javascript html arrays multidimensional-array

我有一个多维数组categories,并且正在使用menuToElement函数遍历该数组。

它将array及其子元素的所有元素取回ul中。代码可以正常工作,但是我不知道是如何仅遍历数组的一个元素及其所有子元素。

例如,我要执行的操作仅是循环搜索引擎元素及其所有子元素和所有子元素数组。我的问题是:我使用的for...of循环是否有可能实现此目标,因为我尝试遍历类别索引并且它说这是不可迭代的。

function menuToElement(menu) {
  const ul = document.createElement("ul");
  for (const item of menu) {
    const li = document.createElement("li");
    if (Object(item) === item) {
      li.textContent = item.text + ' \u25BD';
      li.appendChild(menuToElement(item.children));
    } else {
      li.textContent = item;
    }
    ul.appendChild(li);
  }
  return ul;
}

var categories = [{
  text: "engine",
  children: [1, 2, 3, {
    text: "piston",
    children: [4, 5, 6, {
      text: "piston",
      children: [4, 5, 6]
    }]
  }]
}, {
  text: "tire",
  children: [7, 8, 9]
}];
const ul = menuToElement(categories);
document.getElementById("menu").appendChild(ul);
li>ul {
  display: none;
}

li:hover>ul {
  display: block;
}
<div id="menu"></div>

2 个答案:

答案 0 :(得分:0)

首先,我们从一些帮助我们的生活变得更轻松的助手开始:elemtext-

const elem = (tag, ...children) =>
{ const node = document.createElement(tag)
  children.forEach(node.appendChild.bind(node))
  return node
}

const text =
  document.createTextNode.bind(document)

const doc =
  elem
    ( "article"                    // <article>
    , elem("p", text("wash hand")) //   <p>wash hand</p>
    , elem("p", text("read book")) //   <p>read book</p>
    , elem("p", text("stay safe")) //   <p>stay safe</p>
    )                              // </article>

document.body.appendChild(doc)
article { border: 1px solid tomato; }
p { border: 1px solid dodgerblue; }

接下来,我们定义如何将一个菜单项转换为菜单节点toMenu1-

  1. 如果输入item是对象,则返回带有LI的{​​{1}}并在item.text上调用toMenu
  2. 否则(通过归纳法)输入item.children 不是是一个对象。在这种情况下,只需返回带有纯文本的item
LI

我们还没有写const toMenu1 = (item = {}) => Object(item) === item ? elem('li', text(`${item.text} \u25BD`), toMenu(item.children)) // 1 : elem('li', text(item)) // 2 ,但是在上面我们看到它期望有一系列的项目。编写此函数比上一个要容易-

  1. 返回一个toMenu,其中每个项目都使用UL进行转换
toMenu1

在继续之前,请展开下面的代码片段,以在您自己的浏览器中验证结果-

const toMenu = (all = []) =>
  elem('ul', ...all.map(toMenu1)) // 1
const elem = (tag, ...children) =>
{ const node = document.createElement(tag)
  children.forEach(node.appendChild.bind(node))
  return node
}

const text =
  document.createTextNode.bind(document)

const toMenu1 = (item = {}) =>
  Object(item) === item
    ? elem('li', text(`${item.text} \u25BD`), toMenu(item.children))
    : elem('li', text(item))
    
const toMenu = (all = []) =>
  elem('ul', ...all.map(toMenu1))

var categories = [{
  text: "engine",
  children: [1, 2, 3, {
    text: "piston",
    children: [4, 5, 6, {
      text: "piston",
      children: [4, 5, 6]
    }]
  }]
}, {
  text: "tire",
  children: [7, 8, 9]
}];

const ul = toMenu(categories)
document.getElementById("menu").appendChild(ul)
li>ul {
  display: none;
}

li:hover>ul {
  display: block;
}


现在要回答您的特定问题:我们可以仅使用一个输入项来构建递归菜单吗?

您可以通过以下两种方法之一来执行此操作。 1)仅抓取您关心的物品-

<div id="menu"></div>

或者2)通过使用const ul = toMenu([ categories[0] ]) // just the first category // <ul> // <li>engine<ul>...</ul></li> // </ul> -

Array.prototype.filter

奖金const ul = toMenu(categories.filter(c => c.text === "engine")) // <ul> // <li>engine<ul>...</ul></li> // </ul> toMenu1之间的特殊关系称为mutual recursiontoMenu呼叫toMenu1,后者呼叫toMenu,呼叫toMenu1,依此类推...

答案 1 :(得分:-2)

为此,您需要使用

Array.from()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

因此它用于转换DOM节点(或子节点) 如果您想要更多解释性的评论,请