如何根据特定的 属性 值合并数组项?
How to merge array items according to a specific property value?
我正在尝试找到使用 jQuery 合并此动态数组的最简单方法。
这是我尝试使用 .reduce 后得到的结果。 Month/Year 对象是动态的,结果基于日期范围。
[
{
"ObjectGroupingId": 1,
"Jan 2022": "Project1",
"Feb 2022": 0,
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0
},
{
"ObjectGroupingId": 1,
"Jan 2022": 0,
"Feb 2022": "Project2",
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0
},
{
"ObjectGroupingId": 1,
"Jan 2022": 0,
"Feb 2022": 0,
"Mar 2022": "Project3",
"Apr 2022": 0,
"May 2022": 0
}
]
我想要实现的是这个
[
{
"ObjectGroupingId": 1,
"Jan 2022": "Project1",
"Feb 2022": "Project2",
"Mar 2022": "Project3"
}
]
这是我在 jQuery
中尝试过的
var monthNames = data
.map(function (t) {
var monthName = formatMonthYear(t.dynamicHeaderColumn);
return monthName;
})
.reduce(function (p, t) {
if (p.indexOf(t) == -1)
p.push(t);
return p;
}, []);
// transform
var result = data.reduce(function (p, t) {
var monthName = formatMonthYear(t.dynamicHeaderColumn);
var existing = p.filter(function (t2) {
return t2.objectGroupingId == t.objectGroupingId;
});
if (existing.length) {
existing[0][monthName] = t.projectName;
} else {
var n = {
ObjectGroupingId: t.objectGroupingId
};
monthNames.forEach(function (m) {
n[m] = 0;
});
n[monthName] = t.projectName;
p.push(n);
}
return p;
}, []);
return result;
这可能吗?不是很熟jQuery还在学习
这是使用字典完成此任务的简单方法。我强烈建议您阅读字典的工作原理 - 它们非常有用!
只是对代码的快速解释,在 function(e,d)
中,i
是索引,d
是值。第二个 - function(key, value)
有点不同。 key
将 return :
之前的值而不是索引。这是因为您正在迭代对象的值({
和 }
定义对象的开始和结束)。 value
将 return :
右侧的任何内容。
更新:我更新了代码以允许任意数量的对象组以及纯 JavaScript 版本。
var input = [
{
"ObjectGroupingId": 1,
"Jan 2022": "Project1",
"Feb 2022": 0,
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0
},
{
"ObjectGroupingId": 1,
"Jan 2022": 0,
"Feb 2022": "Project2",
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0
},
{
"ObjectGroupingId": 1,
"Jan 2022": 0,
"Feb 2022": 0,
"Mar 2022": "Project3",
"Apr 2022": 0,
"May 2022": 0,
"Jan 1900": 0
},
{
"ObjectGroupingId": 2,
"Jan 2022": 0,
"Feb 2022": 0,
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0,
"Jan 1900": "Project10"
}
]
var currentObjectGrouping = null;
var outputListJQuery = [];
$.each(input, function(i,d){
$.each(d, function(key, value) {
if(key === 'ObjectGroupingId') currentObjectGrouping = value;
if(outputListJQuery[currentObjectGrouping] === undefined) outputListJQuery[currentObjectGrouping] = {};
if(value !== 0) {
outputListJQuery[currentObjectGrouping][key] = value;
}
});
});
outputListJQuery = outputListJQuery.filter(function( element ) {
return element !== undefined;
})
console.log("This is using JQuery!");
console.log(outputListJQuery);
//Pure JavaScript
var outputListJavascript = [];
input.forEach(e => {
for (const [key, value] of Object.entries(e)) {
if(key === 'ObjectGroupingId') currentObjectGrouping = value;
if(outputListJavascript[currentObjectGrouping] === undefined) outputListJavascript[currentObjectGrouping] = {};
if(value !== 0) {
outputListJavascript[currentObjectGrouping][key] = value;
}
}
});
outputListJavascript = outputListJavascript.filter(function( element ) {
return element !== undefined;
})
console.log("This is using only JavaScript!");
console.log(outputListJavascript);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
在您有多个 ObjectGroupingId
的情况下,最终结果可以是对象的对象,其中 high-level 键是 ObjectGroupingId
值,值是聚合元素。
const data = [{"ObjectGroupingId": 1,"Jan 2022": "Project1","Feb 2022": 0,"Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 1,"Jan 2022": 0,"Feb 2022": "Project2","Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 1,"Jan 2022": 0,"Feb 2022": 0,"Mar 2022": "Project3","Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 2,"Jan 2022": "Project4","Feb 2022": 0,"Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 2,"Jan 2022": 0,"Feb 2022": "Project5","Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 2,"Jan 2022": 0,"Feb 2022": 0,"Mar 2022": "Project6","Apr 2022": 0,"May 2022": 0}];
const aggData = data.reduce((acc, {ObjectGroupingId:id,...rest}) =>
({...acc,[id]:{...acc[id], ...Object.fromEntries(Object.entries(rest).filter(([k,v]) => v !== 0))}}), {}
);
console.log( aggData );
OP 为什么要使用 jQuery? jQuery主要针对查询和操作DOM的域。相比之下,OP 的任务处理单个纯数据结构以及如何 traverse/transform 它。
因此,OP 应该坚持 OP 的原始方法,该方法使用 built-in 对象的方法,例如 Array
和 Object
。
下一个提供的代码示例使用两个嵌套的 reduce
任务以准确实现 OP 的预期结果...
function collectGroupedProjectData({ lookup, result }, { ObjectGroupingId, ...restData }) {
let groupedData = lookup[ObjectGroupingId];
if (!groupedData) {
groupedData = lookup[ObjectGroupingId] = { ObjectGroupingId };
result.push(groupedData);
}
Object
.entries(restData)
.reduce((group, [key, value]) => {
if (value !== 0) {
Object.assign(group, { [key]: value });
}
return group;
}, groupedData);
return { lookup, result };
}
const data = [{
ObjectGroupingId: 1,
'Jan 2022': 'Project1',
'Feb 2022': 0,
'Mar 2022': 0,
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 1,
'Jan 2022': 0,
'Feb 2022': 'Project2',
'Mar 2022': 0,
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 1,
'Jan 2022': 0,
'Feb 2022': 0,
'Mar 2022': 'Project3',
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 2,
'Jan 2022': 'Project4',
'Feb 2022': 0,
'Mar 2022': 0,
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 2,
'Jan 2022': 0,
'Feb 2022': 'Project5',
'Mar 2022': 0,
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 2,
'Jan 2022': 0,
'Feb 2022': 0,
'Mar 2022': 'Project6',
'Apr 2022': 0,
'May 2022': 0,
}];
const listOfGroupedProjects = data
.reduce(collectGroupedProjectData, { lookup: {}, result: [] }).result;
console.log({ listOfGroupedProjects });
.as-console-wrapper { min-height: 100%!important; top: 0; }
我正在尝试找到使用 jQuery 合并此动态数组的最简单方法。
这是我尝试使用 .reduce 后得到的结果。 Month/Year 对象是动态的,结果基于日期范围。
[
{
"ObjectGroupingId": 1,
"Jan 2022": "Project1",
"Feb 2022": 0,
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0
},
{
"ObjectGroupingId": 1,
"Jan 2022": 0,
"Feb 2022": "Project2",
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0
},
{
"ObjectGroupingId": 1,
"Jan 2022": 0,
"Feb 2022": 0,
"Mar 2022": "Project3",
"Apr 2022": 0,
"May 2022": 0
}
]
我想要实现的是这个
[
{
"ObjectGroupingId": 1,
"Jan 2022": "Project1",
"Feb 2022": "Project2",
"Mar 2022": "Project3"
}
]
这是我在 jQuery
中尝试过的var monthNames = data
.map(function (t) {
var monthName = formatMonthYear(t.dynamicHeaderColumn);
return monthName;
})
.reduce(function (p, t) {
if (p.indexOf(t) == -1)
p.push(t);
return p;
}, []);
// transform
var result = data.reduce(function (p, t) {
var monthName = formatMonthYear(t.dynamicHeaderColumn);
var existing = p.filter(function (t2) {
return t2.objectGroupingId == t.objectGroupingId;
});
if (existing.length) {
existing[0][monthName] = t.projectName;
} else {
var n = {
ObjectGroupingId: t.objectGroupingId
};
monthNames.forEach(function (m) {
n[m] = 0;
});
n[monthName] = t.projectName;
p.push(n);
}
return p;
}, []);
return result;
这可能吗?不是很熟jQuery还在学习
这是使用字典完成此任务的简单方法。我强烈建议您阅读字典的工作原理 - 它们非常有用!
只是对代码的快速解释,在 function(e,d)
中,i
是索引,d
是值。第二个 - function(key, value)
有点不同。 key
将 return :
之前的值而不是索引。这是因为您正在迭代对象的值({
和 }
定义对象的开始和结束)。 value
将 return :
右侧的任何内容。
更新:我更新了代码以允许任意数量的对象组以及纯 JavaScript 版本。
var input = [
{
"ObjectGroupingId": 1,
"Jan 2022": "Project1",
"Feb 2022": 0,
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0
},
{
"ObjectGroupingId": 1,
"Jan 2022": 0,
"Feb 2022": "Project2",
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0
},
{
"ObjectGroupingId": 1,
"Jan 2022": 0,
"Feb 2022": 0,
"Mar 2022": "Project3",
"Apr 2022": 0,
"May 2022": 0,
"Jan 1900": 0
},
{
"ObjectGroupingId": 2,
"Jan 2022": 0,
"Feb 2022": 0,
"Mar 2022": 0,
"Apr 2022": 0,
"May 2022": 0,
"Jan 1900": "Project10"
}
]
var currentObjectGrouping = null;
var outputListJQuery = [];
$.each(input, function(i,d){
$.each(d, function(key, value) {
if(key === 'ObjectGroupingId') currentObjectGrouping = value;
if(outputListJQuery[currentObjectGrouping] === undefined) outputListJQuery[currentObjectGrouping] = {};
if(value !== 0) {
outputListJQuery[currentObjectGrouping][key] = value;
}
});
});
outputListJQuery = outputListJQuery.filter(function( element ) {
return element !== undefined;
})
console.log("This is using JQuery!");
console.log(outputListJQuery);
//Pure JavaScript
var outputListJavascript = [];
input.forEach(e => {
for (const [key, value] of Object.entries(e)) {
if(key === 'ObjectGroupingId') currentObjectGrouping = value;
if(outputListJavascript[currentObjectGrouping] === undefined) outputListJavascript[currentObjectGrouping] = {};
if(value !== 0) {
outputListJavascript[currentObjectGrouping][key] = value;
}
}
});
outputListJavascript = outputListJavascript.filter(function( element ) {
return element !== undefined;
})
console.log("This is using only JavaScript!");
console.log(outputListJavascript);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
在您有多个 ObjectGroupingId
的情况下,最终结果可以是对象的对象,其中 high-level 键是 ObjectGroupingId
值,值是聚合元素。
const data = [{"ObjectGroupingId": 1,"Jan 2022": "Project1","Feb 2022": 0,"Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 1,"Jan 2022": 0,"Feb 2022": "Project2","Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 1,"Jan 2022": 0,"Feb 2022": 0,"Mar 2022": "Project3","Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 2,"Jan 2022": "Project4","Feb 2022": 0,"Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 2,"Jan 2022": 0,"Feb 2022": "Project5","Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 2,"Jan 2022": 0,"Feb 2022": 0,"Mar 2022": "Project6","Apr 2022": 0,"May 2022": 0}];
const aggData = data.reduce((acc, {ObjectGroupingId:id,...rest}) =>
({...acc,[id]:{...acc[id], ...Object.fromEntries(Object.entries(rest).filter(([k,v]) => v !== 0))}}), {}
);
console.log( aggData );
OP 为什么要使用 jQuery? jQuery主要针对查询和操作DOM的域。相比之下,OP 的任务处理单个纯数据结构以及如何 traverse/transform 它。
因此,OP 应该坚持 OP 的原始方法,该方法使用 built-in 对象的方法,例如 Array
和 Object
。
下一个提供的代码示例使用两个嵌套的 reduce
任务以准确实现 OP 的预期结果...
function collectGroupedProjectData({ lookup, result }, { ObjectGroupingId, ...restData }) {
let groupedData = lookup[ObjectGroupingId];
if (!groupedData) {
groupedData = lookup[ObjectGroupingId] = { ObjectGroupingId };
result.push(groupedData);
}
Object
.entries(restData)
.reduce((group, [key, value]) => {
if (value !== 0) {
Object.assign(group, { [key]: value });
}
return group;
}, groupedData);
return { lookup, result };
}
const data = [{
ObjectGroupingId: 1,
'Jan 2022': 'Project1',
'Feb 2022': 0,
'Mar 2022': 0,
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 1,
'Jan 2022': 0,
'Feb 2022': 'Project2',
'Mar 2022': 0,
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 1,
'Jan 2022': 0,
'Feb 2022': 0,
'Mar 2022': 'Project3',
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 2,
'Jan 2022': 'Project4',
'Feb 2022': 0,
'Mar 2022': 0,
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 2,
'Jan 2022': 0,
'Feb 2022': 'Project5',
'Mar 2022': 0,
'Apr 2022': 0,
'May 2022': 0,
}, {
ObjectGroupingId: 2,
'Jan 2022': 0,
'Feb 2022': 0,
'Mar 2022': 'Project6',
'Apr 2022': 0,
'May 2022': 0,
}];
const listOfGroupedProjects = data
.reduce(collectGroupedProjectData, { lookup: {}, result: [] }).result;
console.log({ listOfGroupedProjects });
.as-console-wrapper { min-height: 100%!important; top: 0; }