首页 > 解决方案 > 将数组添加到多维数组或对象中

问题描述

我正在将 a 生成的内容解析wysiwyg为 React 中的目录小部件。

到目前为止,我正在遍历标题并将它们添加到数组中。

如何将它们全部放入一个多维数组或对象(最好的方法是什么),使其看起来更像:

h1-1
    h2-1
        h3-1

h1-2
    h2-2
        h3-2

h1-3
    h2-3
        h3-3

然后我可以在 UI 中使用有序列表呈现它。

const str = "<h1>h1-1</h1><h2>h2-1</h2><h3>h3-1</h3><p>something</p><h1>h1-2</h1><h2>h2-2</h2><h3>h3-2</h3>";

const patternh1 = /<h1>(.*?)<\/h1>/g;
const patternh2 = /<h2>(.*?)<\/h2>/g;
const patternh3 = /<h3>(.*?)<\/h3>/g;

let h1s = [];
let h2s = [];
let h3s = [];

let matchh1, matchh2, matchh3;

while (matchh1 = patternh1.exec(str))
    h1s.push(matchh1[1])

while (matchh2 = patternh2.exec(str))
    h2s.push(matchh2[1])
    
while (matchh3 = patternh3.exec(str))
    h3s.push(matchh3[1])
    
console.log(h1s)
console.log(h2s)
console.log(h3s)

标签: javascript

解决方案


我不了解你,但我讨厌使用正则表达式解析 HTML。相反,我认为让 DOM 处理这个更好的主意:

const str = `<h1>h1-1</h1>
  <h3>h3-1</h3>
  <h3>h3-2</h3>
  <p>something</p>
  <h1>h1-2</h1>
  <h2>h2-2</h2>
  <h3>h3-2</h3>`;

const wrapper = document.createElement('div');
wrapper.innerHTML = str.trim();

let tree = [];
let leaf = null;

for (const node of wrapper.querySelectorAll("h1, h2, h3, h4, h5, h6")) {
  const nodeLevel = parseInt(node.tagName[1]);
  const newLeaf = {
    level: nodeLevel,
    text: node.textContent,
    children: [],
    parent: leaf
  };

  while (leaf && newLeaf.level <= leaf.level)
    leaf = leaf.parent;

  if (!leaf)
    tree.push(newLeaf);
  else
    leaf.children.push(newLeaf);

  leaf = newLeaf;
}

console.log(tree);

这个答案不需要h3遵循h2;如果你愿意,h3可以跟随。h1如果你想把它变成一个有序列表,也可以这样做:

const str = `<h1>h1-1</h1>
      <h3>h3-1</h3>
      <h3>h3-2</h3>
      <p>something</p>
      <h1>h1-2</h1>
      <h2>h2-2</h2>
      <h3>h3-2</h3>`;

const wrapper = document.createElement('div');
wrapper.innerHTML = str.trim();

let tree = [];
let leaf = null;

for (const node of wrapper.querySelectorAll("h1, h2, h3, h4, h5, h6")) {
  const nodeLevel = parseInt(node.tagName[1]);
  const newLeaf = {
    level: nodeLevel,
    text: node.textContent,
    children: [],
    parent: leaf
  };

  while (leaf && newLeaf.level <= leaf.level)
    leaf = leaf.parent;

  if (!leaf)
    tree.push(newLeaf);
  else
    leaf.children.push(newLeaf);

  leaf = newLeaf;
}


const ol = document.createElement("ol");

(function makeOl(ol, leaves) {
  for (const leaf of leaves) {
    const li = document.createElement("li");
    li.appendChild(new Text(leaf.text));

    if (leaf.children.length > 0) {
      const subOl = document.createElement("ol");
      makeOl(subOl, leaf.children);
      li.appendChild(subOl);
    }

    ol.appendChild(li);
  }
})(ol, tree);

// add it to the DOM
document.body.appendChild(ol);

// or get it as text
const result = ol.outerHTML;

由于 HTML 由 DOM 而非正则表达式解析,因此如果h1标签具有属性,则此解决方案不会遇到任何错误。


推荐阅读