【问题标题】:Turn groups into concat of arrays javascript将组转换为数组的连接 javascript
【发布时间】:2018-09-02 12:28:03
【问题描述】:

我已经设法根据键值将数组拆分为不同的组。我想要实现的是将这些或多或少的组变成一​​个数组,所以我的组变成[[Regio__c],[Categorie__c]]而不是{Regio__c:[],Categorie__c:[]}。这与普通的 javascript 没有库。

我试过了:return [key].concat.split; 这返回 undefined。

下面是我在 sn-p 中的代码

var filter = [{
    "Id": "120",
    "arrayPicklist": "Categorie__c"
  }, {
    "Id": "121",
    "arrayPicklist": "Regio__c"
  },
  {
    "Id": "122",
    "arrayPicklist": "Categorie__c"
  }, {
    "Id": "123",
    "arrayPicklist": "Regio__c"
  },
  {
    "Id": "121",
    "arrayPicklist": "Regio__c"
  }
]


function splitArrayByValue(arr, key) {
  var split = {};
  for (var i = 0; i < arr.length; i++) {
    var p = arr[i][key];
    if (!split[p]) {
      split[p] = [];
    }
    split[p].push(arr[i])
  }
  return split;
}


var buckets2 = splitArrayByValue(filter, 'arrayPicklist');

console.log(buckets2);

【问题讨论】:

    标签: javascript arrays object filter split


    【解决方案1】:

    您快到了,您需要获取值。另一种方法是使用函数Object.values

    var filter = [{    "Id": "120",    "arrayPicklist": "Categorie__c"  }, {    "Id": "121",    "arrayPicklist": "Regio__c"  },  {    "Id": "122",    "arrayPicklist": "Categorie__c"  }, {    "Id": "123",    "arrayPicklist": "Regio__c"  },  {    "Id": "121",    "arrayPicklist": "Regio__c"  }]
    
    function splitArrayByValue(arr, key) {
      var split = {};
      for (var i = 0; i < arr.length; i++) {
        var p = arr[i][key];
        if (!split[p]) {
          split[p] = [];
        }
        split[p].push(arr[i])
      }
      return Object.values(split);
    }
    
    
    var buckets2 = splitArrayByValue(filter, 'arrayPicklist');
    
    console.log(buckets2);

    您可以使用函数reduce 进行分组,然后使用函数Object.values 来获得所需的输出。

    var filter = [{"Id":"120","arrayPicklist":"Categorie__c"},{"Id":"121","arrayPicklist":"Regio__c"},{"Id":"122","arrayPicklist":"Categorie__c"},{"Id":"123","arrayPicklist":"Regio__c"},{"Id":"121","arrayPicklist":"Regio__c"}];
    
    var result = Object.values(filter.reduce((a, {Id, arrayPicklist}) => {
      (a[arrayPicklist] || (a[arrayPicklist] = [])).push({Id, arrayPicklist});      
      return a;
    }, {}));
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案2】:

      只需在 splitArrayByValue 函数中返回 Object.values(split) 而不是 split

      var filter = [{"Id":"120","arrayPicklist":
      "Categorie__c"},{"Id":"121","arrayPicklist":"Regio__c"},
      {"Id":"122","arrayPicklist":"Categorie__c"},{"Id":"123","arrayPicklist":"Regio__c"},
      {"Id":"121","arrayPicklist":"Regio__c"}]
      
      
      function splitArrayByValue(arr, key) {
        var split = {};
        for (var i=0; i<arr.length; i++) {
          var p = arr[i][key];
          if (!split[p]) { split[p] = []; }
          split[p].push(arr[i])
        }
        return Object.values(split);//<---- just return Object.values(split) instead of split 
      }
      
      
      var buckets2 = splitArrayByValue(filter,'arrayPicklist');
      
      console.log(buckets2);

      【讨论】:

        【解决方案3】:

        你可以使用.reduce():

        let data = [
          {"Id":"120", "arrayPicklist":"Categorie__c"},
          {"Id":"121", "arrayPicklist":"Regio__c"},
          {"Id":"122", "arrayPicklist":"Categorie__c"},
          {"Id":"123", "arrayPicklist":"Regio__c"},
          {"Id":"121", "arrayPicklist":"Regio__c"}
        ];
        
        let keys = [...new Set(data.map(({arrayPicklist}) => arrayPicklist))];
        
        /* 
         * let keys = ["Categorie__c", "Regio__c"];
         * In case you wants to use hard code values
         */
        
        let result = data.reduce((r, c) => (
            r[keys.indexOf(c["arrayPicklist"])].push(c), r
        ), [[], []]);
        
        console.log(result);
        .as-console-wrapper { max-height: 100% !important; top: 0; }

        有用的资源:

        【讨论】:

          【解决方案4】:

          制作一组所有可能的类别 (arrayPicklist)。对于这个集合中的每个值,过滤数组并创建一个组:

          var array = [
              {"Id": "120", "arrayPicklist": "Categorie__c"},
              {"Id": "121", "arrayPicklist": "Regio__c"},
              {"Id": "122", "arrayPicklist": "Categorie__c"},
              {"Id": "123", "arrayPicklist": "Regio__c"},
              {"Id": "121", "arrayPicklist": "Regio__c"}
          ]
          
          let groups = [...new Set(array.map(x => x.arrayPicklist))]
              .map(p => array.filter(x => x.arrayPicklist === p));
          
          console.log(groups)

          也就是说,您真的应该考虑使用库。精心设计和经过良好测试的工具总是优于任何可以想出的 javascript 内置插件的脆弱临时组合。有了lodash,你的问题就一行解决了:

          let groups = _.values(_.groupBy(array, 'arrayPicklist'))
          

          就像Ramda

          let groups  = R.values(R.groupBy(x => x.arrayPicklist, array))
          

          【讨论】:

          • +1。看到你的回答后,我有点纳闷,因为这问题并没有我想象的那么复杂。
          【解决方案5】:

          如果我理解正确,您希望将对象的值作为数组获取。您可以使用以下方法实现此目的:

          1. Object.values:

          当你从splitArrayByValue返回时,返回这个:

          return Object.values(split);
          

          代替:

          return split;
          

          Object.values 仅在 ECMAScript 2017 中有效。如果您使用的是旧版 ECMA,则使用第二种方法,它可以达到相同的效果

          2。 Object.keys & Array#map:

          如上,不是直接返回split,而是返回这个:

          return Object.keys(split).map(function(key) {
            return split[key];
          });
          

          使用箭头函数或更短:

          return Object.keys(split).map(key => split[key]);
          

          注意:上述两种方法都没有指定子数组的顺序。它可以是任何东西。可能是 [[Regio__c], [Categorie__c]],也可能是 [[Categorie__c], [Regio__c]],因为 javascript 中的对象不保留其键值对的顺序。

          【讨论】:

            【解决方案6】:

            我了解您希望得到一个二维数组,其中第一级表示 arrayPicklist 值。如果这是正确的,您可以使用 mapSet 来实现您想要的,例如

            var filter = [{"Id":"120","arrayPicklist":
            "Categorie__c"},{"Id":"121","arrayPicklist":"Regio__c"},
            {"Id":"122","arrayPicklist":"Categorie__c"},{"Id":"123","arrayPicklist":"Regio__c"},
            {"Id":"121","arrayPicklist":"Regio__c"}]
            
            
            function splitArrayByValue(arr, key) {
              let keys = arr.map(entry => {
                return entry[key];
              });
            
              let unique = [...new Set(keys.concat())]; 
            
              let split = new Array(unique.length);
              for (var i = 0; i < arr.length; i++) {
                let p = arr[i][key];
                let index = unique.indexOf(p);
            
                if (!split[index]) split[index] = [];
                split[index].push(arr[i])
              }
              return split;
            }
            
            
            var buckets2 = splitArrayByValue(filter,'Id');
            
            console.log(buckets2);
            

            【讨论】:

              猜你喜欢
              • 2018-05-30
              • 2013-05-26
              • 2011-08-02
              • 1970-01-01
              • 1970-01-01
              • 2015-09-22
              • 2018-12-16
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多