我正在从数据库中提取数据,最后得到一个对象数组,每个对象包含服务员姓名及其工作日。我想通过将数组压缩为每个服务员具有两个属性值对的单个对象来动态重组数组。一个属性用于名称,另一属性用于工作日。
我真的很想知道您的反馈。我首先提取名称并删除重复项。留给我这样的数组:let waiterNames = ['John','Mark','Jess'].
然后,我尝试使用double for循环,并以某种方式创建了新的对象数组,但是我陷入了困境。
for (entry in waiterInfo) {
for (waiter in waiterNames) {
if (entry.waiters == waiter) {
???
}
}
}
waiterInfo
是我开始的目标,newInfo
是我要实现的目标。我需要动态地进行此操作,因为从数据库中提取的数据是不可预测的。
let waiterInfo = [{ waiters: 'John', weekdays: 'Monday' },
{ waiters: 'John', weekdays: 'Tuesday' },
{ waiters: 'John', weekdays: 'Wednesday' },
{ waiters: 'Mark', weekdays: 'Monday' },
{ waiters: 'Mark', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Monday' },
{ waiters: 'Jess', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Wednesday' },
{ waiters: 'Jess', weekdays: 'Thursday' }]
let newInfo = [{ waiters: 'John', weekdays: 'Monday, Tuesday, Wednesday'},
{ waiters: 'Mark', weekdays: 'Monday, Tuesday' },
{ waiters: 'Jess', weekdays: 'Monday, Tuesday, Wednesday, Thursday' }]
您可以使用带有reduce
的集:
let waiterInfo = [{ waiters: 'John', weekdays: 'Monday' },
{ waiters: 'John', weekdays: 'Tuesday' },
{ waiters: 'John', weekdays: 'Wednesday' },
{ waiters: 'Mark', weekdays: 'Monday' },
{ waiters: 'Mark', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Monday' },
{ waiters: 'Jess', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Wednesday' },
{ waiters: 'Jess', weekdays: 'Thursday' }
]
const map = new Map([])
const newInfo = waiterInfo.reduce((a, o) => {
const i = map.get(o.waiters)
if(i !== undefined) {
a[i].weekdays = [a[i].weekdays, o.weekdays].join(', ')
} else {
map.set(o.waiters, a.push(o) - 1)
}
return a
}, [])
console.log(newInfo)
此代码的时间复杂度为O(n),因为我们使用的是地图。
最简单的方法是使用临时Map
来跟踪您之前见过的服务员的对象,因此您可以将其添加到工作日列表中。
const waiterMap = new Map();
const newInfo = [];
for (const {waiters, weekdays} of waiterInfo) {
let entry = waiterMap.get(waiters);
if (!entry) {
// New waiter, create the object and put it in the map and result array
const copy = {waiters, weekdays};
waiterMap.set(waiters, copy);
newInfo.push(copy);
} else {
// Existing entry, just add to it
entry.weekdays += `, ${weekdays}`;
}
}
实时示例:
let waiterInfo = [{ waiters: 'John', weekdays: 'Monday' },
{ waiters: 'John', weekdays: 'Tuesday' },
{ waiters: 'John', weekdays: 'Wednesday' },
{ waiters: 'Mark', weekdays: 'Monday' },
{ waiters: 'Mark', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Monday' },
{ waiters: 'Jess', weekdays: 'Tuesday' },
{ waiters: 'Jess', weekdays: 'Wednesday' },
{ waiters: 'Jess', weekdays: 'Thursday' }];
const waiterMap = new Map();
const newInfo = [];
for (const {waiters, weekdays} of waiterInfo) {
let entry = waiterMap.get(waiters);
if (!entry) {
// New waiter, create the object and put it in the map and result array
const copy = {waiters, weekdays};
waiterMap.set(waiters, copy);
newInfo.push(copy);
} else {
// Existing entry, just add to it
entry.weekdays += `, ${weekdays}`;
}
}
console.log(newInfo);
这避免了修改现有数据,但是如果您不在乎waiterInfo
,则可以重用原始对象。
您可以使用Array.prototype.reduce():
const waiterInfo = [{ waiters: 'John', weekdays: 'Monday' },{ waiters: 'John', weekdays: 'Tuesday' },{ waiters: 'John', weekdays: 'Wednesday' },{ waiters: 'Mark', weekdays: 'Monday' },{ waiters: 'Mark', weekdays: 'Tuesday' },{ waiters: 'Jess', weekdays: 'Monday' },{ waiters: 'Jess', weekdays: 'Tuesday' },{ waiters: 'Jess', weekdays: 'Wednesday' },{ waiters: 'Jess', weekdays: 'Thursday' },]
const result = Object.values(waiterInfo.reduce((a, {waiters, weekdays}) => {
a[waiters] = a[waiters] || { waiters, weekdays: [] }
a[waiters].weekdays += `, ${weekdays}`
return a
}, []))
console.log(result)