我有一个对象数组,它有这样的结构:
days : string // "mo","tu","we"..
time : string // "9am - 3pm"
当我有2个(甚至更多)具有相同days
值的对象时,有时会发生。在这种情况下,我需要合并这些项目(改变time
值,从这个"相同"的项目连接值)
var array = [{
days: "mo,tu,we,th",
time: "9am - 3pm"
}, {
days: "mo,tu,we,th",
time: "5pm - 9pm"
}, {
days: "sa,su",
time: "9am - 2pm"
}];
var newArr = [];
for (var i = 0; i < array.length; i++) {
var currItem = array[i];
var mergedArray = [];
array.forEach(function(el) {
if (currItem.days == el.days) {
mergedArray.push(el.time);
}
});
var mergedTime = mergedArray.join(', ');
currItem.time = mergedTime;
if (newArr.filter(function(item) {
return item.days == currItem.days;
}).length < 1) {
newArr.push(currItem);
}
}
console.log(newArr);
这是我看到的,如何合并数组项,但我不喜欢它,因为里面有很多循环。有没有更优雅的解决方案?可以使用lodash
使用_可以得到预期的结果。uniqWith和篡改对象引用。
如果您不想修改原始数组,您可以将数组的_. clonedeep传递给_。uniqWith函数。
var arr = [{
days: "mo,tu,we,th",
time: "9am - 3pm"
}, {
days: "mo,tu,we,th",
time: "5pm - 9pm"
}, {
days: "sa,su",
time: "9am - 2pm"
}];
console.log(_.uniqWith(arr, function(a, b) {
if (a.days === b.days) {
b.time += ', ' + a.time;
return true;
}
}));
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
你可以在javascript中使用2个循环,而不需要任何库:
var array = [{
days: "mo,tu,we,th",
time: "9am - 3pm"
}, {
days: "mo,tu,we,th",
time: "5pm - 9pm"
}, {
days: "sa,su",
time: "9am - 2pm"
}];
tmp = {};
array.forEach(function(item) {
if (tmp.hasOwnProperty(item.days)) {
tmp[item.days] = tmp[item.days] + ',' + item.time;
} else {
tmp[item.days] = item.time;
}
});
res = [];
for(var days in tmp) {
res.push({'days' : days, time: tmp[days]});
}
console.log(res);
按天用_.groupBy()
分组,每组再用_.mergeWith()
分组:
var array = [{
days: "mo,tu,we,th",
time: "9am - 3pm"
}, {
days: "mo,tu,we,th",
time: "5pm - 9pm"
}, {
days: "sa,su",
time: "9am - 2pm"
}];
var result = _(array)
.groupBy('days')
.map(function(days) {
return _.mergeWith.apply(_, [{}].concat(days, function(obj, src, key) {
if (key === 'time' && obj && src) {
return [obj, src].join(', ');
}
}));
})
.values()
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
和更漂亮的ES6版本:
var array = [{
days: "mo,tu,we,th",
time: "9am - 3pm"
}, {
days: "mo,tu,we,th",
time: "5pm - 9pm"
}, {
days: "sa,su",
time: "9am - 2pm"
}];
var result = _(array)
.groupBy('days')
.map((days) => _.mergeWith({}, ...days, (obj, src, key) => {
if (key === 'time' && obj && src) {
return [obj, src].join(', ');
}
}))
.values()
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.4/lodash.min.js"></script>
您可以使用这个ES6函数,它依赖于Set
和Map
实例来完成它的工作:
function groupDays(array) {
return Array.from(
array.reduce((acc, {days, time}) =>
acc.set(days, (acc.get(days) || new Set()).add(time)),
new Map()),
([days, times]) => ({ days, time: [...times].join(', ') })
);
}
// Sample data
var array = [{
days: "mo,tu,we,th",
time: "9am - 3pm"
}, {
days: "mo,tu,we,th",
time: "5pm - 9pm"
}, {
days: "sa,su",
time: "9am - 2pm"
}];
// group
array = groupDays(array);
// result
console.log(array);