我正在从数据库中提取数据,最后得到一个对象数组,每个对象都包含服务员姓名和他们工作的天数。 我想通过将数组压缩为单个对象来动态重组数组,每个服务员有两个属性值对。 一个属性用于名称,另一个属性用于工作日。
我真的很想看到你的反馈。 我从提取名称并删除重复项开始。 给我留下这样的数组:let waiterNames = ['John','Mark','Jess'].
然后我尝试双 for of 循环并以某种方式创建一个新的对象数组,但我被卡住了。
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),因为我们使用的是映射。
(另外,这是我唯一一次看到push
的返回值有用😜)
你可以做:
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.push(weekdays)
return a
}, {})
)
.map(({ waiters, weekdays }) => ({ waiters, weekdays: weekdays.join(', ') }))
console.log(result)
最简单的方法是使用临时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
,则可以重用原始对象。