如果属性值为true,则由多个属性组成Lodash组

时间:2016-10-19 19:10:31

标签: javascript lodash

我有一系列需要按品牌和型号分组的车辆,只有在选中'财产是真的。生成的对象应包含make model和count的属性。使用lodash,如何将车辆对象组织到所需的结果对象中。我可以通过makeCode获取车辆对象,但我不确定如何按多个属性进行分组。

分组制作代码

      var vehicles = _.groupBy(response.vehicleTypes, function(item)
      {
        return item.makeCode; // how to group by model code as well
      });

初始车辆

{
    id: 1, 
    selected: true, 
    makeCode: "Make-A", 
    modelCode: "Model-a", 
    trimCode: "trim-a", 
    yearCode: "2012"
},
{
    id: 2, 
    selected: false, 
    makeCode: "Make-A", 
    modelCode: "Model-a", 
    trimCode: "trim-a", 
    yearCode: "2013"
},
{
    id: 3, 
    selected: true, 
    makeCode: "Make-B", 
    modelCode: "Model-c", 
    trimCode: "trim-a", 
    yearCode: "2014"
},
{
    id: 25, 
    selected: true, 
    makeCode: "Make-C", 
    modelCode: "Model-b", 
    trimCode: "trim-b", 
    yearCode: "2012"
},
{
    id: 26, 
    selected: true, 
    makeCode: "Make-C", 
    modelCode: "Model-b", 
    trimCode: "trim-a", 
    yearCode: "2013"
}

结果对象

{
    Make-A: {
        Model-a: {
            count: 1
        }
    }
},

{
    Make-B: {
        Model-c: {
            count: 1
        }
    }
},
{
    Make-C: {
        Model-b: {
            count: 2
        }
    }
}

8 个答案:

答案 0 :(得分:12)

由于您已经在使用lodash,因此您可以利用_.filter功能。这将仅返回selected为真的项目。

var selectedVehicles = _.filter(response.vehicleTypes, 'selected');

现在您已拥有selectedVehicles数组,您可以使用原始代码按makeCode进行分组。

selectedVehicles = _.groupBy(selectedVehicles, function(item) {
  return item.makeCode;
});

这会返回一个对象,因此我们需要遍历这些键,并执行第二个groupBy

_.forEach(selectedVehicles, function(value, key) {
  selectedVehicles[key] = _.groupBy(selectedVehicles[key], function(item) {
    return item.modelCode;
  });
});

从这里你将有一个表格的对象。我会留给你从每个阵列得到计数。

{ 'Make-A': { 'Model-a': [ ... ] },
  'Make-B': { 'Model-c': [ ... ] },
  'Make-C': { 'Model-b': [ ..., ... ] } }

答案 1 :(得分:12)

我不确定这是否会解决您的问题,但在group_by中您可以添加允许您创建复合键的自定义逻辑。

_.chain(data).filter((item) => item.selected).groupBy((item)=>`${item.model}--${item.type}`)

答案 2 :(得分:4)

您可以使用Array.prototype.reduce(),并在一个循环O(n)中执行此操作:

var arr = [{"id":1,"selected":true,"makeCode":"Make-A","modelCode":"Model-a","trimCode":"trim-a","yearCode":"2012"},{"id":2,"selected":false,"makeCode":"Make-A","modelCode":"Model-a","trimCode":"trim-a","yearCode":"2013"},{"id":3,"selected":true,"makeCode":"Make-B","modelCode":"Model-c","trimCode":"trim-a","yearCode":"2014"},{"id":25,"selected":true,"makeCode":"Make-C","modelCode":"Model-b","trimCode":"trim-b","yearCode":"2012"},{"id":26,"selected":true,"makeCode":"Make-C","modelCode":"Model-b","trimCode":"trim-a","yearCode":"2013"},{"id":29,"selected":false,"makeCode":"Make-A","modelCode":"Model-g","trimCode":"trim-a","yearCode":"2013"},{"id":2,"selected":true,"makeCode":"Make-A","modelCode":"Model-h","trimCode":"trim-a","yearCode":"2013"}];

var result = arr.reduce(function(map, obj) {
  if(!obj.selected) {
    return map;
  }
  
  var makeCode = map[obj.makeCode] = map[obj.makeCode] || {};
  
  var modelCode = makeCode[obj.modelCode] = makeCode[obj.modelCode] || { count: 0 };
  
  modelCode.count++;
  
  return map;
}, Object.create(null));

console.log(result);

答案 3 :(得分:2)

如果您关注结果,以下代码将起作用:

在我的情况下,“品牌”和“商品代码”是属性

            const products = _.groupBy(this.productsTable.data, (item) => {
                return [item['Brand'], item['Item Code']];
            });

答案 4 :(得分:0)

const result = _.chain(vehicles)
.filter('selected')
.groupBy('makeCode')
.mapValues(values => _.chain(values)
    .groupBy('modelCode')
    .mapValues(_.size)
    .value()
)
.value()

答案 5 :(得分:0)

const multiGroupBy = (array, group, ...restGroups) => {
  if(!group) {
    return array;
  }
  const currGrouping = _.groupBy(array, group);
  if(!restGroups.length) {
    return currGrouping;
  }
  return _.transform(currGrouping, (result, value, key) => {
    result[key] = multiGroupBy(value, ...restGroups);
  }, {});
};

console.log(multiGroupBy([{x:1,y:1,z:1},{x:1,y:2,z:1},{x:2,y:1,z:1},{x:2,y:2,z:1},{x:1,y:1,z:2},{x:1,y:2,z:2},{x:2,y:1,z:2},{x:2,y:2,z:2}],'x','y'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

或者如果您喜欢旧语法

function multiGroupBy(array, group) {
  if(!group) {
    return array;
  }
  var currGrouping = _.groupBy(array, group);
  var restGroups = Array.prototype.slice.call(arguments);
  restGroups.splice(0,2);
  if(!restGroups.length) {
    return currGrouping;
  }
  return _.transform(currGrouping, function(result, value, key) {
    result[key] = multiGroupBy.apply(null, [value].concat(restGroups));
  }, {});
}

console.log(multiGroupBy([{x:1,y:1,z:1},{x:1,y:2,z:1},{x:2,y:1,z:1},{x:2,y:2,z:1},{x:1,y:1,z:2},{x:1,y:2,z:2},{x:2,y:1,z:2},{x:2,y:2,z:2}],'x','y'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

答案 6 :(得分:0)

在纯JS上对没有LODASH的对象或数组进行分组和过滤:

// Группировка и фильтрация объекта или массива без LODASH на чистом JS:
let k = "HUID", // group by; 
input = [
{HUID:11,test:1},
{HUID:11,test:111},
{HUID:'eeeeeeeeeeee',test:11111},
{HUID:22,test:2},
{HUID:33,test:3}
],
result = input.reduce((map, obj) => { 
//if(!obj.selected) { return map; } 
let makeCode = (map[obj[k]] = map[obj[k]] || {}); // var modelCode = makeCode[obj.HUID] = makeCode[obj.HUID] || { count: 0 }; 
let l = map[obj[k]],
    m = Object.keys(l).length; 
l[m] = { ...obj }; 
return map; 
}, {} );
console.log(result);

Copied from VK

答案 7 :(得分:0)

您不需要重复所有的数组对象。使用loadash,您可以简化如下操作:

_.mapValues(_.groupBy(object, 'yourKeys'))