假设我必须给列表中明天有约会的人发送电子邮件, 但是,当我编写电子邮件主题时,我想知道谁明天有多个约会,因此可以配置主题。 另外,我也不想一次发送多封电子邮件。我想发送一封电子邮件,说您已经预约或明天要预约多个。 (知道这些约会的ID也很高兴。)
所以我有以下内容:
AllAppointments: [
{
id: 23,
name: "John",
email: "John@domain.com",
appointment_date: tomorrow,
appointment_category: 3,
time: "morning"
}, {
id: 17,
name: "Alex",
email: "Alex @domain.com",
appointment_date: tomorrow,
appointment_category: 3,
time: "morning"
},
{
id: 22,
name: "Bob",
email: "Bob@domain.com",
appointment_date: tomorrow,
appointment_category: 5,
time: "morning"
}, {
id: 35,
name: "John",
email: "John@domain.com",
appointment_date: tomorrow,
appointment_category: 4,
time: "afternoon"
}
]
我想要这些
MultipleAppointments : [
{
ids :[23,35],
name : John,
email : John@domain.com,
appointment_date : tomorrow,
appointment_categories: [ 3, 5 ]
}
]
singleAppointments : [
{
id: 17,
name : “Alex",
email : “Alex@domain.com",
appointment_date : tomorrow,
appointment_category: 3,
time: “morning"
},
{
id: 22,
name : “Bob",
email : “Bob@domain.com",
appointment_date : tomorrow,
appointment_categories: 5,
time: “morning"
}
]
答案 0 :(得分:1)
我不仅会在这里给出答案,还将向您介绍如何解决。它有助于将您想做的事情分解为更小的步骤,并考虑您要与正在处理的具体数据类型分开进行的高级操作。
第一步是一个常见问题,许多实用程序库都提供了一个groupBy
函数。 groupBy
将对象数组和从每个对象到字符串的函数作为参数,然后返回对象数组的数组。提供的函数为其返回相同值的对象将一起放置在同一数组中。对于您的情况,您可以这样呼叫groupBy
:
const groupedAppointments = groupBy(appointments, appointment => appointment.name);
尝试自己实施groupBy
是一个很好的学习练习。作为提示,请尝试使用for
循环或Array.reduce。
现在,我们有了对象数组,就像这样:
[
[{
id: 23,
name: "John",
email: "John@domain.com",
appointment_date: tomorrow,
appointment_category: 3,
time: "morning"
}, {
id: 35,
name: "John",
email: "John@domain.com",
appointment_date: tomorrow,
appointment_category: 4,
time: "afternoon"
}],
[{
id: 17,
name: "Alex",
email: "Alex @domain.com",
appointment_date: tomorrow,
appointment_category: 3,
time: "morning"
}],
[{
id: 22,
name: "Bob",
email: "Bob@domain.com",
appointment_date: tomorrow,
appointment_category: 5,
time: "morning"
}]
]
我们要分离出内部数组,并使一个变量保存所有单个约会,而另一个变量保存所有多个约会。 JavaScript有一个内置方法,用于处理像这样的数组filter。筛选器采用“测试程序”功能,并将其应用于数组中的每个对象,然后返回一个新数组,其中包含测试程序针对其返回true
的所有值。因此,我们可以使用它来创建两个数组,一个包含其中只有一个项目的组,另一个包含其中一个以上项目的组:
const singleGroups = groupedAppointments.filter(group => group.length === 1);
const multipleGroups = groupedAppointments.filter(group => group.length > 1);
现在,singleGroups
仍然是约会数组,每个内部数组仅包含一个项目。看起来像这样:
[
[{
id: 17,
name: "Alex",
email: "Alex @domain.com",
appointment_date: tomorrow,
appointment_category: 3,
time: "morning"
}],
[{
id: 22,
name: "Bob",
email: "Bob@domain.com",
appointment_date: tomorrow,
appointment_category: 5,
time: "morning"
}]
]
我们要用包含的每个内部数组替换每个内部数组。如果要以相同的方式转换数组中的每个项目,则可以使用内置的Array.map方法。这需要一个函数,该函数转换单个元素,并将其应用于数组中的每个项目。因此,要“取消组合”单个项目,我们将像这样使用它:
const singleAppointments = singleGroups.map(group => group[0]);
现在,singleAppointments
包含了您想要的内容,这些约会只发生一次了:
[{
id: 17,
name: "Alex",
email: "Alex @domain.com",
appointment_date: tomorrow,
appointment_category: 3,
time: "morning"
}, {
id: 22,
name: "Bob",
email: "Bob@domain.com",
appointment_date: tomorrow,
appointment_category: 5,
time: "morning"
}]
最后,我们需要将所有multipleGroups
数组中的约会组转换为问题中具有“ MultipleAppointments”形的对象。这意味着我们有一个数组数组,我们想要一个对象数组,其中每个内部数组都变成一个对象,这是再次使用Array.map
的理想情况:
const multipleAppointments = multipleGroups.map(groupToMultipleAppointment);
function groupToMultipleAppointment(group) {
// ???
}
现在剩下的就是实现groupToMultipleAppointment
了,它需要像这样的约会数组:
[{
id: 23,
name: "John",
email: "John@domain.com",
appointment_date: tomorrow,
appointment_category: 3,
time: "morning"
}, {
id: 35,
name: "John",
email: "John@domain.com",
appointment_date: tomorrow,
appointment_category: 4,
time: "afternoon"
}]
并返回这样的对象:
{
ids:[23, 35],
name: John,
email: John@domain.com,
appointment_date: tomorrow,
appointment_categories: [3, 5]
}
我将groupToMultipleAppointment
的实现留给您;我建议使用for
循环或Array.reduce
。
因此,总的来说,这是我建议的代码,其中有些部分尚待您填写:
const groupedAppointments = groupBy(appointments, appointment => appointment.name);
const singleGroups = groupedAppointments.filter(group => group.length === 1);
const multipleGroups = groupedAppointments.filter(group => group.length > 1);
const singleAppointments = singleGroups.map(group => group[0]);
const multipleAppointments = multipleGroups.map(groupToMultipleAppointment);
function groupToMultipleAppointment(group) {
// ???
// `group` is an array. Use `reduce` or a `for` loop to make a new object out of it.
}
function groupBy(array, getKeyForArray) {
// ???
// getKeyForArray is a function which takes an item from `array` and returns a string
// use a `for` loop or `reduce` to make a new array where
// objects with the same key are grouped together.
}
答案 1 :(得分:0)
首先告诉您该数据的存储位置。 Mongodb? MySQL的?记忆吗?
然后改变思维方式。您需要知道的是,您向哪一封电子邮件发送了多个通知,而不是谁召开了多少次会议。建议您不要使用2个一维表,而是一个多维表:
mails: {
'John@domain.com': [
{
id: 23,
name: "John",
email: "John@domain.com",
appointment_date: tomorrow,
appointment_category: 3,
time: "morning"
}, {
id: 35,
name: "John",
email: "John@domain.com",
appointment_date: tomorrow,
appointment_category: 4,
time: "afternoon"
}
]
'Alex@domain.com': [{
id: 17,
name: "Alex",
email: "Alex@domain.com",
appointment_date: tomorrow,
appointment_category: 3,
time: "morning"
}
]
'Bob@domain.com': [{
id: 22,
name: "Bob",
email: "Bob@domain.com",
appointment_date: tomorrow,
appointment_category: 5,
time: "morning"
}]
}
这样的东西很容易创建。
let mails = {};
AllAppointments.forEach(one=> {
if(!mails[one.email])
mails[one.email] = [];
mails[one.email].push(one)
})
for(let email in mails)
sendMail(mails[email])