我有一系列需要按品牌和型号分组的车辆,只有在选中'财产是真的。生成的对象应包含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
}
}
}
答案 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);
答案 7 :(得分:0)
您不需要重复所有的数组对象。使用loadash,您可以简化如下操作:
_.mapValues(_.groupBy(object, 'yourKeys'))