我有一个数组:
[
{
assignmentId:17,
email:"john.smith@email.com"
expectation: "Make sure to proofread!",
firstName:"John"
id:23
ignoreForFeedback: true
lastName:"Smith"
level:2
levelFraction:null
score:35
},
{
assignmentId:17
countsPerCategory: Array(4)
email:"john.smith@email.com"
firstName:"John"
frequentErrors: Array(5)
id:23
ignoreForGrading: true
lastName:"Smith"
},
{
assignmentId:17,
email:"cl@email.com"
expectation: "cite sources",
firstName:"Cindy"
id:45
ignoreForFeedback: true
lastName:"Lee"
level:2
levelFraction:null
score:32
},
{
assignmentId:17
countsPerCategory: Array(4)
email:"cl@email.com"
firstName:"Cindy"
frequentErrors: Array(5)
id:45
ignoreForGrading: true
lastName:"Lee"
}
]
我想将对象与相同的&id;#id;进入数组中的同一个对象。他们的共同键也应该组合在一起(例如:' firstName',' email')。有人可以建议最好的方法吗?使用ES6或Lodash
答案 0 :(得分:4)
您可以使用lodash#groupBy
按id
对数组中的所有项目进行分组,然后使用lodash#map
,其lodash#assign
的迭代包含lodash#spread
将数组回调作为lodash#assgin
的参数列表。
var result = _(array)
.groupBy('id')
.map(_.spread(_.assign))
.value();
var array = [
{
assignmentId:17,
email:"john.smith@email.com",
expectation: "Make sure to proofread!",
firstName:"John",
id:23,
ignoreForFeedback: true,
lastName:"Smith",
level:2,
levelFraction:null,
score:35
},
{
assignmentId:17,
countsPerCategory: Array(4),
email:"john.smith@email.com",
firstName:"John",
frequentErrors: Array(5),
id:23,
ignoreForGrading: true,
lastName:"Smith"
},
{
assignmentId:17,
email:"cl@email.com",
expectation: "cite sources",
firstName:"Cindy",
id:45,
ignoreForFeedback: true,
lastName:"Lee",
level:2,
levelFraction:null,
score:32
},
{
assignmentId:17,
countsPerCategory: Array(4),
email:"cl@email.com",
firstName:"Cindy",
frequentErrors: Array(5),
id:45,
ignoreForGrading: true,
lastName:"Lee"
}
];
var result = _(array)
.groupBy('id')
.map(_.spread(_.assign))
.value();
console.log(result);

body > div { min-height: 100%; top: 0; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
&#13;
这是一个使用Array#filter
的替代解决方案,它利用了Array#filter
的第二个参数,它为过滤器的回调函数提供了上下文。我们使用this
上下文作为一种机制来存储缓存对象的id
,然后使用它来决定是否从数组中保留这些对象。
var result = array.filter(function(v) {
return this[v.id]?
!Object.assign(this[v.id], v):
(this[v.id] = v);
}, {});
var array = [
{
assignmentId:17,
email:"john.smith@email.com",
expectation: "Make sure to proofread!",
firstName:"John",
id:23,
ignoreForFeedback: true,
lastName:"Smith",
level:2,
levelFraction:null,
score:35
},
{
assignmentId:17,
countsPerCategory: Array(4),
email:"john.smith@email.com",
firstName:"John",
frequentErrors: Array(5),
id:23,
ignoreForGrading: true,
lastName:"Smith"
},
{
assignmentId:17,
email:"cl@email.com",
expectation: "cite sources",
firstName:"Cindy",
id:45,
ignoreForFeedback: true,
lastName:"Lee",
level:2,
levelFraction:null,
score:32
},
{
assignmentId:17,
countsPerCategory: Array(4),
email:"cl@email.com",
firstName:"Cindy",
frequentErrors: Array(5),
id:45,
ignoreForGrading: true,
lastName:"Lee"
}
];
var result = array.filter(function(v) {
// does this `id` exist?
return this[v.id]?
// assign existing object with the same id
// from the `this` cache object. Make sure
// to negate the resulting object with a `!`
// to remove this value from the array
!Object.assign(this[v.id], v):
// Assign the value from the `this` cache.
// This also retains this value from the existing
// array
(this[v.id] = v);
}, {});
console.log(result);
&#13;
body > div { min-height: 100%; top: 0; }
&#13;
答案 1 :(得分:1)
您可以使用JavaScript内置的Array.reduce()
方法。我们的想法是,您可以使用ID创建地图,并使用lodash.merge()
方法(或您选择用于合并对象的任何方法)将具有相同ID的所有对象合并到单个对象中。然后,您可以在创建的.map()
上使用idMap
将对象恢复为单个数组。
var data = [{
assignmentId: 17,
email: "john.smith@email.com",
expectation: "Make sure to proofread!",
firstName: "John",
id: 23,
ignoreForFeedback: true,
lastName: "Smith",
level: 2,
levelFraction: null,
score: 35
},
{
assignmentId: 17,
countsPerCategory: Array(4),
email: "john.smith@email.com",
firstName: "John",
frequentErrors: Array(5),
id: 23,
ignoreForGrading: true,
lastName: "Smith"
},
{
assignmentId: 17,
email: "cl@email.com",
expectation: "cite sources",
firstName: "Cindy",
id: 45,
ignoreForFeedback: true,
lastName: "Lee",
level: 2,
levelFraction: null,
score: 32
},
{
assignmentId: 17,
countsPerCategory: Array(4),
email: "cl@email.com",
firstName: "Cindy",
frequentErrors: Array(5),
id: 45,
ignoreForGrading: true,
lastName: "Lee"
}
];
var idMap = data.reduce(function(result, current) {
if (result[current.id] == null) {
result[current.id] = current;
} else {
_.merge(result[current.id], current);
}
return result;
}, {});
var results = Object.keys(idMap).map(function(key) {
return idMap[key];
});
console.log(results);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
答案 2 :(得分:1)
我可以建议使用forEach()
和some()
方法的组合来迭代数组元素并测试迭代对象id是否已经处理过。
这是解决方案:
var merged = [];
arr.forEach(function(item) {
var idx;
var found = merged.some(function(el, i) {
idx = el.id === item.id ? i : null;
return el.id === item.id;
});
if (!found) {
merged.push(item);
} else if (idx !== null) {
for (k in Object.keys(item)) {
if (item.hasOwnProperty(k)) {
merged[idx][k] = item[k];
}
}
}
});
工作演示:
var arr = [{
assignmentId: 17,
email: "john.smith@email.com",
expectation: "Make sure to proofread!",
firstName: "John",
id: 23,
ignoreForFeedback: true,
lastName: "Smith",
level: 2,
levelFraction: null,
score: 35
},
{
assignmentId: 17,
countsPerCategory: [],
email: "john.smith@email.com",
firstName: "John",
frequentErrors: [],
id: 23,
ignoreForGrading: true,
lastName: "Smith"
},
{
assignmentId: 17,
email: "cl@email.com",
expectation: "cite sources",
firstName: "Cindy",
id: 45,
ignoreForFeedback: true,
lastName: "Lee",
level: 2,
levelFraction: null,
score: 32
},
{
assignmentId: 17,
countsPerCategory: [],
email: "cl@email.com",
firstName: "Cindy",
frequentErrors: [],
id: 45,
ignoreForGrading: true,
lastName: "Lee"
}
];
var merged = [];
arr.forEach(function(item) {
var idx;
var found = merged.some(function(el, i) {
idx = el.id === item.id ? i : null;
return el.id === item.id;
});
if (!found) {
merged.push(item);
} else if (idx !== null) {
for (k in Object.keys(item)) {
if (item.hasOwnProperty(k)) {
merged[idx][k] = item[k];
}
}
}
});
console.log(merged);
答案 3 :(得分:0)
感谢大家的帮助,但我最终选择了自己的实施方式。
let ids = [];
let combinedUsers = [];
users.forEach(function (user) {
ids.push(user.id);
});
ids = _.uniq(ids);
ids.forEach(function(id){
let user = users.filter(function(userObj){
return id === userObj.id
});
if(user.length > 1){
user = Object.assign(user[0], user[1]);
combinedUsers.push(user);
} else {
combinedUsers.push(user[0]);
}
});
return combinedStudents;