如何从javascript中具有相同键的对象创建对象数组
我有一个像这样的对象数组如何从javascript中具有相同键的对象创建对象数组,javascript,arrays,node.js,underscore.js,lodash,Javascript,Arrays,Node.js,Underscore.js,Lodash,我有一个像这样的对象数组 [{ "name": "Agile Process", "id": 27, "score": 3, "source": "Self" },{ "name": "Agile Process", "id": 27, "score": 4, "source": "Trainer" },{ "name": "2 &
[{
"name": "Agile Process",
"id": 27,
"score": 3,
"source": "Self"
},{
"name": "Agile Process",
"id": 27,
"score": 4,
"source": "Trainer"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 4,
"source": "Self"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 5,
"source": "Trainer"
}]
我希望能够生产出这样的产品,我一直在努力,但我似乎没有掌握它
[
{
"name": "Agile Process",
"id": 7,
"data": [
{
"score": 3,
"source": "Self"
},{
"score": 4,
"source": "Trainer"
}
]
},
{
"name": "2 & 3 Tier Architecture",
"id": 37,
"data": [
{
"score": 4,
"source": "Self"
},{
"score": 5,
"source": "Trainer"
}]
}
];
如何着手解决这个问题?这里有一个纯javascript解决方案:在初始数组上使用reduce方法,将存储转换数据的结果数组(首先为空)用作累加器。当reduce方法遍历初始数组的项时,检查结果数组是否包含id为当前项的元素。如果是这样,那么只需向其中添加新数据,否则在结果数组中创建一个新项
var data = [{
"name": "Agile Process",
"id": 27,
"score": 3,
"source": "Self"
},{
"name": "Agile Process",
"id": 27,
"score": 4,
"source": "Trainer"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 4,
"source": "Self"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 5,
"source": "Trainer"
}];
var newData = [];
newData = data.reduce(function(acc, current) {
var existingArr = acc.filter(function(x) { return x.id === current.id });
if(existingArr.length === 0) {
acc.push({ name: current.name, id: current.id, data: [{ score: current.score, source: current.source }] });
}
else {
existingArr[0].data.push({ score: current.score, source: current.source });
}
return acc;
}, newData);
这里有一个纯javascript解决方案:在初始数组上使用reduce方法,将存储转换数据的结果数组(首先为空)用作累加器。当reduce方法遍历初始数组的项时,检查结果数组是否包含id为当前项的元素。如果是这样,那么只需向其中添加新数据,否则在结果数组中创建一个新项
var data = [{
"name": "Agile Process",
"id": 27,
"score": 3,
"source": "Self"
},{
"name": "Agile Process",
"id": 27,
"score": 4,
"source": "Trainer"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 4,
"source": "Self"
},{
"name": "2 & 3 Tier Architecture",
"id": 37,
"score": 5,
"source": "Trainer"
}];
var newData = [];
newData = data.reduce(function(acc, current) {
var existingArr = acc.filter(function(x) { return x.id === current.id });
if(existingArr.length === 0) {
acc.push({ name: current.name, id: current.id, data: [{ score: current.score, source: current.source }] });
}
else {
existingArr[0].data.push({ score: current.score, source: current.source });
}
return acc;
}, newData);
一种可能的办法:
_.values(_.reduce(arr, function(acc, el) {
var id = el.id;
if (!acc.hasOwnProperty(id)) {
acc[id] = _.pick(el, 'id', 'name');
acc[id].data = [];
}
acc[id].data.push(_.pick(el, 'score', 'source'));
return acc;
}, {}));
。当您需要将事情分组时,这是一种常见的方法。一种可能的方法:
_.values(_.reduce(arr, function(acc, el) {
var id = el.id;
if (!acc.hasOwnProperty(id)) {
acc[id] = _.pick(el, 'id', 'name');
acc[id].data = [];
}
acc[id].data.push(_.pick(el, 'score', 'source'));
return acc;
}, {}));
。当您需要对项目进行分组时,这是一种常用方法。此版本用于按id对项目进行分组,然后在每个分组之间映射以创建所需的对象:
var groupToItem = function(items){
return {
id: items[0].id,
name: items[0].name,
data: _.map(items, function(item){
return _.pick(item, 'score', 'source');
})
}
}
var result = _.chain(data)
.groupBy('id')
.map(groupToItem)
.value();
此版本使用按id对项目进行分组,然后跨每个分组映射以创建所需的对象:
var groupToItem = function(items){
return {
id: items[0].id,
name: items[0].name,
data: _.map(items, function(item){
return _.pick(item, 'score', 'source');
})
}
}
var result = _.chain(data)
.groupBy('id')
.map(groupToItem)
.value();
纯Javascript解决方案,仅适用于您的特定数据结构:
function groupObjectsById(array){
var output = [];
var ids = [];
for(var i = 0; i < array.length; i++){
var current = array[i];
if(ids.indexOf(current.id) > -1){
var objInOutput = output.filter(function(obj){
if(obj.id === current.id){
return obj;
}
})[0];
var dataObj = { score: current.score, source: current.source};
objInOutput.data.push(dataObj);
}else{
var outputObject = {name: current.name, id: current.id};
outputObject.data = [{ score: current.score, source: current.source}];
output.push(outputObject);
ids.push(current.id);
}
}
return output;
}
函数组objectsbyid(数组){
var输出=[];
var-id=[];
对于(var i=0;i-1){
var objinpoutput=output.filter(函数(obj){
if(obj.id==current.id){
返回obj;
}
})[0];
var dataObj={score:current.score,source:current.source};
objinpoutput.data.push(dataObj);
}否则{
var outputObject={name:current.name,id:current.id};
outputObject.data=[{score:current.score,source:current.source}];
output.push(outputObject);
id.push(当前的id);
}
}
返回输出;
}
纯Javascript解决方案,仅适用于您的特定数据结构,但:
function groupObjectsById(array){
var output = [];
var ids = [];
for(var i = 0; i < array.length; i++){
var current = array[i];
if(ids.indexOf(current.id) > -1){
var objInOutput = output.filter(function(obj){
if(obj.id === current.id){
return obj;
}
})[0];
var dataObj = { score: current.score, source: current.source};
objInOutput.data.push(dataObj);
}else{
var outputObject = {name: current.name, id: current.id};
outputObject.data = [{ score: current.score, source: current.source}];
output.push(outputObject);
ids.push(current.id);
}
}
return output;
}
函数组objectsbyid(数组){
var输出=[];
var-id=[];
对于(var i=0;i-1){
var objinpoutput=output.filter(函数(obj){
if(obj.id==current.id){
返回obj;
}
})[0];
var dataObj={score:current.score,source:current.source};
objinpoutput.data.push(dataObj);
}否则{
var outputObject={name:current.name,id:current.id};
outputObject.data=[{score:current.score,source:current.source}];
output.push(outputObject);
id.push(当前的id);
}
}
返回输出;
}
这是真正的火箭科学+1这是真正的火箭科学+1感谢@all。。。我将使用这个解决方案。。。原因仍然存在,这一点有待改进:运行过滤器函数总是会降低性能,尤其是当原始数组包含许多对象时。我的解决方案缓存ID,这使它更快。谢谢@all。。。我将使用这个解决方案。。。原因仍然存在,这一点有待改进:运行过滤器函数总是会降低性能,尤其是当原始数组包含许多对象时。我的解决方案缓存ID,这使它更快。