简体   繁体   English

按Javascript对象键+数组分组

[英]Group by Javascript Object keys + array

I am trying to use underscore to group my array of objects in a smaller list: 我正在尝试使用下划线将对象数组分组在一个较小的列表中:

    var list = [
  { Region: 'A', Vals: [ 7, 'H' ] },
  { Region: 'B', Vals: [ 40, 'H' ] },
  { Region: 'B', Vals: [ 24, 'VH' ] },
  { Region: 'C', Vals: [ 4, 'VH' ] },
  { Region: 'A',Vals: [ 40, 'VH' ] }
  ];


    var groups = _.groupBy(list, function(value){
        return value.Region;
    });

var grouped = _.map(groups, function(group){
        return {
            Region: group[0].Region,
            Vals: group[0].Vals
        }
    });

Which will get somewhat close, but it is missing some of the Vals. 它将有些接近,但是缺少一些Val。 I want the arrays of 'vals' concatenated based on keys. 我想要基于键连接的“ vals”数组。

   var list = [
  { Region: 'A', Vals: [ 7, 'H', 40, 'VH' ] },
  { Region: 'B', Vals: [ 40, 'H',  24, 'VH' ] },
  { Region: 'B', Vals: [ 24, 'VH' ] },
  { Region: 'C', Vals: [ 4, 'VH' ] }
  ];

http://jsfiddle.net/77gL11c9/1/ http://jsfiddle.net/77gL11c9/1/

list.reduce(function (memo, v) {
  if (memo[v.Region]) {
    memo[v.Region] = memo[v.Region].concat(v.Vals)
  } else {
    memo[v.Region] = v.Vals.slice()
  }
  return memo
}, {})

The output will look like this: 输出将如下所示:

{
  A: [ 7, "H", 40, "VH" ],
  B: [40, "H", 24, "VH" ],
  C: [ 4, "VH" ]
}

Use native JavaScript Array#reduce method with a reference object to hold the index. 将原生JavaScript Array#reduce方法与参考对象一起使用以保存索引。

 var list = [ { Region: 'A', Vals: [ 7, 'H' ] }, { Region: 'B', Vals: [ 40, 'H' ] }, { Region: 'B', Vals: [ 24, 'VH' ] }, { Region: 'C', Vals: [ 4, 'VH' ] }, { Region: 'A',Vals: [ 40, 'VH' ] } ]; // object for refering index var ref = {}; // iterate over the array var res = list.reduce(function(arr, v) { // check property defined if not define and push // value to array if (!(v.Region in ref)) { ref[v.Region] = arr.length; arr.push({Region: v.Region, Vals: v.Vals}); // if index already defined then push values } else{ [].push.apply(arr[ref[v.Region]].Vals, v.Vals); } // return the array reference return arr; // set initial value as empty array }, []); console.log(res); 


UPDATE : If you want to generate an object where Region value as property name and Vals value as it's value then do something like this. 更新:如果要生成一个对象,其中Region值作为属性名, Vals值作为其值,则执行以下操作。

 var list = [ { Region: 'A', Vals: [ 7, 'H' ] }, { Region: 'B', Vals: [ 40, 'H' ] }, { Region: 'B', Vals: [ 24, 'VH' ] }, { Region: 'C', Vals: [ 4, 'VH' ] }, { Region: 'A',Vals: [ 40, 'VH' ] } ]; // iterate over the array var res = list.reduce(function(obj, v) { // define the property as an array if not // already defined obj[v.Region] = obj[v.Region] || []; // push all values to array [].push.apply(obj[v.Region], v.Vals); // return the object reference return obj; // set initial value as an empty object }, {}); console.log(res); 

This will produce the exact output that you are looking for. 这将产生您想要的确切输出。

//first build an object with Region properties, and add the Vals to each of those properties

var tempList = {}; 
for (var i=0; i < list.length; i++) {
  if (!(list[i].Region in tempList)) {
    tempList[list[i].Region] = [];
  }
  Array.prototype.push.apply(tempList[list[i].Region],list[i].Vals);
}

//then format this as an array of objects    
var groupedList = [];
for (var region in tempList) {
    groupedList.push({Region:region, Vals: tempList[region]});
}

list = groupedList;

After the above code, the following will be true: 在上面的代码之后,以下内容将成立:

list = [
  { Region: 'A', Vals: [ 7, 'H', 40, 'VH' ] },
  { Region: 'B', Vals: [ 40, 'H',  24, 'VH' ] },
  { Region: 'B', Vals: [ 24, 'VH' ] },
  { Region: 'C', Vals: [ 4, 'VH' ] }
];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM