地图深入 collection

map deep in collection

我需要得到我拥有的大 collection 中的所有 "id" 和 "name"。一个数组 ob objects,其中包含 objects(等)的数组。

如果不对尽可能多的级别手动执行 foreaches,我无法让它工作,这很丑陋。

我正在使用 Lodash,所以使用它的解决方案会很不错。

这是 collection 的样子:

[
  {
    "id": 1,
    "name": "Living",
    "numberStories": 0,
    "subcategories": {
      "data": [
        {
          "id": 2,
          "name": "Fashion",
          "numberStories": 0,
          "subcategories": {
            "data": [
              {
                "id": 3,
                "name": "Accessories",
                "numberStories": 0,
                "subcategories": {
                  "data": [

                  ]
                }
              },
              {
                "id": 4,
                "name": "Kid's Fashion",
                "numberStories": 0,
                "subcategories": {
                  "data": [

                  ]
                }
              }, (... etc)

所以它需要在 objects 的每个数组中查找子类别并收集 id 和名称,这样我最终得到所有级别的所有 ids 名称。

谢谢。

没有必要为此使用 lodash。使用 .reduce() 的简单递归函数可以为您完成工作

function flattenId(inArray){
 return inArray.reduce(function(output, elem){
   output.push(elem.id);
   return output.concat(flattenId(elem.subcategories.data));
  }, []);
}

如上所述,使用原生 javascript 可能更容易做到这一点,因为它是递归的。这与之前的答案相同,但使用了 ES6 的一些很酷的特性(解构、rest 参数、箭头函数、默认参数),并且它会保存对父 id 的引用,以便您可以在需要时重建类别树.

const categories=[{id:1,name:"Living",numberStories:0,subcategories:{data:[{id:2,name:"Fashion",numberStories:0,subcategories:{data:[{id:3,name:"Accessories",numberStories:0,subcategories:{data:[]}},{id:4,name:"Kid's Fashion",numberStories:0,subcategories:{data:[]}}]}}]}}];

const flattenCategories = (categories, parent = null, ret = []) =>
  categories.reduce((acc, { id, name, subcategories: { data } }) =>
    acc.concat(
      { id, name, parent },
      ...flattenCategories(data, id)
    )
  , ret)


console.log(
  flattenCategories(categories)
)
.as-console-wrapper { top: 0; max-height: 100% !important }

这是一个使用 object-scan 的解决方案。根据您的用例,使用库可能有点矫枉过正,但如果需要,它可以为您提供更大的灵活性

// const objectScan = require('object-scan');

const categories = [{ id: 1, name: 'Living', numberStories: 0, subcategories: { data: [{ id: 2, name: 'Fashion', numberStories: 0, subcategories: { data: [{ id: 3, name: 'Accessories', numberStories: 0, subcategories: { data: [] } }, { id: 4, name: "Kid's Fashion", numberStories: 0, subcategories: { data: [] } }] } }] } }];

const r = objectScan(['**[*].id'], {
  filterFn: ({ context, value, parents }) => {
    context.push({
      id: value,
      name: parents[0].name,
      parent: parents.length > 2 ? parents[3].id : null
    });
  }
})(categories, []);

console.log(r);
// => [ { id: 4, name: "Kid's Fashion", parent: 2 }, { id: 3, name: 'Accessories', parent: 2 }, { id: 2, name: 'Fashion', parent: 1 }, { id: 1, name: 'Living', parent: null } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>

免责声明:我是object-scan

的作者