【问题标题】:How to build a nested array of objects without duplicates in javascript如何在javascript中构建没有重复的嵌套对象数组
【发布时间】:2017-08-04 08:38:41
【问题描述】:

我的要求是,如果我在客户端为订阅选择一个类别,那么我将发送与该类别相关的类别详细信息,并将这些详细信息与一些 id 一起存储在我的后端,然后推送回客户端在一个部分中向我的用户显示这些类别。所以我会得到一个像下面这样来自我的后端数据库的数组

[
  {
   catId:"veg",
   catName:"vegetarian",
   subCatId:"potato", 
   subcatName:"potatoes"
  },
  {
   catId:"veg",
   catName:"vegetarian",
   subCatId:"tomato", 
   subcatName:"tomatoes"
  },
  {
   catId:"nonveg",
   catName:"Non vegetarians",
   subCatId:"chicken", 
   subcatName:"chicken"
  },
  {
   catId:"apetizer",
   catName:"Apitizers",
   subCatId:"veg-apitizer", 
   subcatName:"vegetarian Apitizers"
  }  
]

现在我想要如下的结果数组,

  [
     {
      catId:"veg",
      catName:"vegetarian",
      subcatsArray:[
                     {
                       catId:"veg",
                       catName:"vegetarian",
                       subCatId:"potato",
                       subcatName:"potatoes"
                      }, 
                      {
                       catId:"veg",
                       catName:"vegetarian",
                       subCatId:"tomato", 
                       subcatName:"tomatoes"
                      }
                    ]
     },
     {
      catId:"nonveg",
      catName:"Non vegiterians",
      subcatsArray:[
                     {
                       catId:"nonveg",
                       catName:"Non vegiterians",
                       subCatId:"chicken",
                       subcatName:"chicken"
                      }
                    ]
     },{
      catId:"apetizer",
      catName:"Apitizers",
      subcatsArray:[
                     {
                       catId:"apetizer",
                       catName:"Apitizers",
                       subCatId:"veg-apitizer",
                       subcatName:"vegetarian Apitizers"
                      }
                    ]
     }

    ]

如果我再次订阅另一个子类别,那么我想将该子类别推送到 subcatsArray 的相关类别数组中,如上面的模型结构所示。

注意:我在另一个页面中显示生成的订阅类别,当我订阅类别时,子类别在单独的页面中

【问题讨论】:

  • 同时发布您尝试的代码。
  • 另外,我认为您不需要 catIdcatName in subcatsArray,因为这只是数据的重复。

标签: javascript angularjs arrays for-loop


【解决方案1】:

这是我认为你所追求的开端。

var catarray = [];//your array
var formatedArray = [];    
function sort() {

      for (var i=0; i < catarray.length; i++) {
          addToFormated(Stored_Rights[i].catId,Stored_Rights[i].catName, Stored_Rights[i].subCatId,Stored_Rights[i].subcatName);

      }
    }
    function addToFormated(a,b,c,d) {
       var found = false;
       for (var i=0; i < formatedArray.length; i++) {
          if (formatedArray[i].catId == a) {
              found = true;
             //add the cat food to this area of the array
          }
       }
       if (!found) {
          //create a new catagory and add
       }
    }

【讨论】:

    【解决方案2】:

    您可以使用嵌套哈希表并仅获取不在结果集中的部分。

    var array = [{ catId: "veg", catName: "vegetarian", subCatId: "potato", subcatName: "potatoes" }, { catId: "veg", catName: "vegetarian", subCatId: "potato", subcatName: "potatoes" }, { catId: "veg", catName: "vegetarian", subCatId: "tomato", subcatName: "tomatoes" }, { catId: "nonveg", catName: "Non vegetarians", subCatId: "chicken", subcatName: "chicken" }, { catId: "apetizer", catName: "Apitizers", subCatId: "veg-apitizer", subcatName: "vegetarian Apitizers" }],
        hash = Object.create(null),
        result = [];
    
    array.forEach(function (o) {
        if (!hash[o.catId]) {
            hash[o.catId] = { _: [] };
            result.push({ catId: o.catId, catName: o.catName, subcatsArray: hash[o.catId]._ });
        }
        if (!hash[o.catId][o.subCatId]) {
            hash[o.catId][o.subCatId] = o;
            hash[o.catId]._.push(o);
        }
    });
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案3】:
      <div id="log"></div>
      <script>
      var source = [{
              catId: "veg",
              catName: "vegetarian",
              subCatId: "potato",
              subcatName: "potatoes"
          },
          {
              catId: "veg",
              catName: "vegetarian",
              subCatId: "tomato",
              subcatName: "tomatoes"
          },
          {
              catId: "nonveg",
              catName: "Non vegetarians",
              subCatId: "chicken",
              subcatName: "chicken"
          },
          {
              catId: "apetizer",
              catName: "Apitizers",
              subCatId: "veg-apitizer",
              subcatName: "vegetarian Apitizers"
          }
      ];
      
      var treestructure = []; // keep this in global scope
      
      window.onload = function() {
          flat2tree(source);
          document.getElementById('log').innerHTML = JSON.stringify(treestructure);
      }
      
      function flat2tree(source) {
          for (var i in source) {
              var cat = source[i]['catId'];
              // see if the cat is already in the treestructure
              var index = inTree(treestructure, 'catId', cat);
              if (index > -1) {
                  // add this item to the subarray
                  treestructure[index]['subcatsArray'].push(source[i]);
              } else {
                  // new category, add to tree
                  treestructure.push({
                      catId: cat,
                      catName: source[i]['catName'],
                      subcatsArray: [
                          source[i]
                      ]
                  });
              }
          }
      }
      
      // a kind of inArray, or indexOf, but especially for this kind of tree.  returns -1 for 'not found', else returns the index
      function inTree(obj, tag, value) {
          for (var i in obj) {
              if (obj[i][tag] == value) {
                  return i;
              }
          }
          return -1;
      }
      </script>
      

      【讨论】:

        【解决方案4】:

        使用 es6,您可以通过使用像 Map 和 Reduce 这样的集合来做一些简短的事情,对 catid 进行哈希处理,然后将值传播到一个数组中。或者您可以使用闭包并遵循 Ninas 模式。但是,Nina 的解决方案更快、更优雅,因为她的解决方案只包含一个循环,这是解决问题的最直接的解决方案。

        const catagoriseDuplicates = list => [...list.reduce((map, list) =>
          (map.has(list.catId) ? map.get(list.catId).subCatArray.every(x => x.subCatId !== list.subCatId) ? map.get(list.catId).subCatArray.push(list) : null : map.set(list.catId, {
            catId: list.catId,
            catName: list.catName,
            subCatArray: []
          }) && map.get(list.catId).subCatArray.push(list), map), new Map()).values()];
        
        
        let list = [{
            catId: "veg",
            catName: "vegetarian",
            subCatId: "potato",
            subcatName: "potatoes"
          },
          {
            catId: "veg",
            catName: "vegetarian",
            subCatId: "tomato",
            subcatName: "tomatoes"
          },
          {
            catId: "nonveg",
            catName: "Non vegetarians",
            subCatId: "chicken",
            subcatName: "chicken"
          },
          {
            catId: "apetizer",
            catName: "Apitizers",
            subCatId: "veg-apitizer",
            subcatName: "vegetarian Apitizers"
          }
        ]
        console.log(catagoriseDuplicates(list));
        .as-console-wrapper {
          max-height: 100% !important;
          top: 0;
        }

        使用 Reduce 的闭包

        const catagoriseDuplicates = list => list.reduce((hash => (map, list) => {
          !hash[list.catId] ? (hash[list.catId] = {
              _: []
            },
            map.push({
              catId: list.catId,
              catName: list.catName,
              subCatsArray: hash[list.catId]._
            })) : null;
          !hash[list.catId][list.subCatId] ? (hash[list.catId][list.subCatId] = list,
            hash[list.catId]._.push(list)) : null;
          return map
        })(Object.create(null)), []);
        
        
        let list = [{
            catId: "veg",
            catName: "vegetarian",
            subCatId: "potato",
            subcatName: "potatoes"
          }, {
            catId: "veg",
            catName: "vegetarian",
            subCatId: "potato",
            subcatName: "potatoes"
          },
          {
            catId: "veg",
            catName: "vegetarian",
            subCatId: "tomato",
            subcatName: "tomatoes"
          },
          {
            catId: "nonveg",
            catName: "Non vegetarians",
            subCatId: "chicken",
            subcatName: "chicken"
          },
          {
            catId: "apetizer",
            catName: "Apitizers",
            subCatId: "veg-apitizer",
            subcatName: "vegetarian Apitizers"
          }
        ]
        console.log(catagoriseDuplicates(list));

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-04
          • 2018-02-27
          • 2015-05-06
          • 1970-01-01
          • 2019-03-21
          • 1970-01-01
          • 1970-01-01
          • 2020-04-15
          相关资源
          最近更新 更多