从数组动态创建嵌套对象?

时间:2021-07-29 08:57:23

标签: javascript arrays loops puppeteer

我正在尝试使用 puppeteer 在网站上创建链接列表。如果网页有链接,请转到该链接并获取链接。 我可以将链接作为 myArr 之类的数组获取,现在我想将它们格式化为对象。 我在从数组创建嵌套对象时遇到问题。我可以像这样从数组创建嵌套对象吗? 或者还有其他好的方法吗?

预期输出:

myObjFromArr = [
   {
      "keyword":"a",
      "children":[
         {
            "keyword":"d",
            "children":[
               {
                  "keyword":"k"
               },
               {
                  "keyword":"l"
               }
            ]
         },
         {
            "keyword":"e",
            "children":[
               {
                  "keyword":"m"
               }
            ]
         },
         {
            "keyword":"f"
         }
      ]
   },
   {
      "keyword":"b",
      "children":[
         {
            "keyword":"g"
         }
      ]
   },
   {
      "keyword":"c",
      "children":[
         {
            "keyword":"h"
         },
         {
            "keyword":"i"
         },
         {
            "keyword":"j"
         }
      ]
   }
  ...
]

我做了什么:

  1. 使用 puppeteer 获取链接列表数组。
let count = 0;
let childrenArray = [];

for (let i = 0; i < keywords.length; i++) {
  const keyword = keywords[i];

  if (count < 20) {
    await new Promise((resolve) => setTimeout(resolve, 1000));
    await page.goto(`someurl/${keyword}`);
    count++;

    childArray = await page.$$eval(selector, (list) => {
      return list.map((data) =>
        data.href
      );
    });

    childrenArray[i] = childArray;
  }

  let allKeywords = keywords;
  childrenArray[i] = childrenArray[i].map((item) => {
    allKeywords.push(item);
  });
}

await browser.close();
  1. 我有一个这样的数组:
myArr = [['a', 'b' , 'c'], ['d', 'e', 'f'], ['g'],['h', 'i', 'j'],['k', 'l'],['m']...] 

但不知道如何格式化这个数组来创建链接树?

1 个答案:

答案 0 :(得分:1)

您可以使用递归函数 transform,如下所示。

每次调用递归函数都需要计算previous items的个数,再次传递给递归函数,得到下一个子数组的相关位置。

data = [
  ["a", "b", "c"],
  ["d", "e", "f"],
  ["g"],
  ["h", "i", "j"],
  ["k", "l"],
  ["m"],
];

const transform = (arr, index) => {
  const store = [];
  if (index < arr.length) {
    let prevItems = 0;

    //get number of previous items
    if (index > 0) {
      for (let j = 0; j < index; j++) {
        for (let k = 0; k < arr[j].length; k++) {
          prevItems += 1;
        }
      }
    }

    for (let i = 0; i < arr[index].length; i++) {
      const obj = transform(arr, i + prevItems + 1);
      if (obj.length) {
        store.push({ keyword: arr[index][i], children: obj });
      } else {
        store.push({ keyword: arr[index][i] });
      }
    }
  }
  return store;
};

const o = transform(data, 0);

console.log(o);