我从数据库中选择基本上连接主实体和子实体,如下面的示例(汽车与零件)作为片段
我想按汽车零件的所有按键进行分组,并有一系列零件,但包括汽车和零件的所有按键。对于groupBy我可以找到的例子,通常它使用groupBy,但它只对一个键组合。我能够使用大量的解决方法,但我确信使用es6或lodash可以实现相同的可管理性(并获得更高的性能)。
有人可以帮我解决这个问题吗?我尝试过多个groupBy并减少组合,但无法正确链接。
var data = [{id: 'car1',
name: 'name for car 1',
description: 'description for car1',
partId: 'partId1',
partName: 'partName1'},
{id: 'car1',
name: 'name for car 1',
description: 'description for car1',
partId: 'partId2',
partName: 'partName2'},
{id: 'car2',
name: 'name for car 2',
description: 'description for car2',
partId: 'partId3',
partName: 'partName3'},
{id: 'car2',
name: 'name for car 2',
description: 'description for car2',
partId: 'partId4',
partName: 'partName4'}
];
var dictionary = {};
data.forEach(function(item, index, array)
{
var masterDocument = null;
if (typeof dictionary[item.id] === 'undefined')
{
masterDocument = {
id: item.id,
name: item.name,
description: item.description,
parts: []
};
dictionary[item.id] = masterDocument;
}
else {
var masterDocument = dictionary[item.id];
}
masterDocument.parts.push({
partId: item.partId,
partName: item.partName
})
})
var asList = [];
Object.keys(dictionary).forEach((item) => {
asList.push(dictionary[item])
});
console.log(asList);

.as-console-wrapper {
min-height: 100%;
top: 0;
}

这里是我想要实现的结果的片段。
[
{
"id": "car1",
"name": "name for car 1",
"description": "description for car1",
"parts": [
{
"partId": "partId1",
"partName": "partName1"
},
{
"partId": "partId2",
"partName": "partName2"
}
]
},
{
"id": "car2",
"name": "name for car 2",
"description": "description for car2",
"parts": [
{
"partId": "partId3",
"partName": "partName3"
},
{
"partId": "partId4",
"partName": "partName4"
}
]
}
]

答案 0 :(得分:2)
以下代码可以使用Lodash解决您的问题。基本上你想要做的是:
id
id
,name
和description
(因为你知道这组中的所有车都是一样的)。保存这些以供稍后返回对象partId
和partName
,然后将其放入{ {1}}数组parts
以启动Lodash序列
valueOf()

let data = [{id: 'car1',
name: 'name for car 1',
description: 'description for car1',
partId: 'partId1',
partName: 'partName1'},
{id: 'car1',
name: 'name for car 1',
description: 'description for car1',
partId: 'partId2',
partName: 'partName2'},
{id: 'car2',
name: 'name for car 2',
description: 'description for car2',
partId: 'partId3',
partName: 'partName3'},
{id: 'car2',
name: 'name for car 2',
description: 'description for car2',
partId: 'partId4',
partName: 'partName4'}
];
const carsInfo = _(data)
.groupBy('id')
.map(carGrouping => {
// all cars in this array have the same id, name, description, so just grab them from the first one
const firstCarInGroup = _.first(carGrouping);
const id = firstCarInGroup.id;
const name = firstCarInGroup.name;
const description = firstCarInGroup.description;
// do a nested map call to iterate over each car in the carGrouping, and grab their partId and partName, and return it in an object
const parts = _.map(carGrouping, car => {
return {
partId: car.partId,
partName: car.partName
}
});
return {
id,
name,
description,
parts
}
})
.valueOf();
console.log(carsInfo);

答案 1 :(得分:2)
这个不使用依赖项。简单的ES6 +。
const data = [{
id: 'car1',
name: 'name for car 1',
description: 'description for car1',
partId: 'partId1',
partName: 'partName1'
},
{
id: 'car1',
name: 'name for car 1',
description: 'description for car1',
partId: 'partId2',
partName: 'partName2'
},
{
id: 'car2',
name: 'name for car 2',
description: 'description for car2',
partId: 'partId3',
partName: 'partName3'
},
{
id: 'car2',
name: 'name for car 2',
description: 'description for car2',
partId: 'partId4',
partName: 'partName4'
}
];
const nested = data.reduce((acc, part) => {
let index = acc.findIndex(car => car.id === part.id)
const { partId, partName, ...car } = part
if (index === -1) {
acc.push({
...car,
parts: [],
})
index = acc.length - 1
}
acc[index].parts.push({
partId,
partName,
})
return acc
}, [])
console.log(JSON.stringify(nested, null, ' '));