从其他数组中的多个对象创建对象数组

问题描述 投票:0回答:2

假设我必须通过电子邮件发送我的列表中明天有约会的人,但是当我写电子邮件的主题时,我想知道谁明天有多个约会,所以我可以配置主题。此外,我不想一次发送多封电子邮件。我想发一封电子邮件说你有预约,或者你明天有多个预约。 (知道那些约会的身份也很棒。)

所以我有以下几点:

AllAppointments: [
    {
        id: 23,
        name: "John",
        email: "[email protected]",
        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: "[email protected]",
        appointment_date: tomorrow,
        appointment_category: 5,
        time: "morning"
    }, {
        id: 35,
        name: "John",
        email: "[email protected]",
        appointment_date: tomorrow,
        appointment_category: 4,
        time: "afternoon"
    }

]

我想得到这些

MultipleAppointments : [

        {
            ids :[23,35],
            name : John,
            email : [email protected],
            appointment_date : tomorrow,
            appointment_categories: [ 3, 5  ]
        }
]

singleAppointments : [ 

        { 
            id: 17,
            name : “Alex",
            email : “[email protected]",
            appointment_date : tomorrow,
            appointment_category:  3,
            time: “morning"
        },


        { 
            id: 22,
            name : “Bob",
            email : “[email protected]",
            appointment_date : tomorrow,
            appointment_categories:  5,
             time: “morning"
        }


]
javascript node.js
2个回答
1
投票

我不打算在这里给出答案,而是告诉你如何解决它。它有助于将您想要执行的操作分解为更小的步骤,并将您想要执行的高级操作与您正在处理的具体数据类型分开考虑。

  • 首先,您希望基于它们共有的键将一些对象组合在一起
  • 其次,您希望将包含1个对象的组与包含多个对象的组分开
  • 第三,您希望将每个“多个约会”组中的所有对象组合到一个新对象中。

第一步是一个常见问题,许多实用程序库提供了groupBy函数来完成它。 groupBy将一个对象数组和一个函数从每个对象作为参数作为参数,并返回一个对象数组的数组。提供的函数返回相同值的对象将一起放在同一个数组中。对于您的情况,您可以这样调用groupBy

const groupedAppointments = groupBy(appointments, appointment => appointment.name);

尝试为自己实施groupBy是一个很好的学习练习。作为提示,尝试使用for循环或Array.reduce

现在,我们有一个对象数组数组,如下所示:

[
  [{
    id: 23,
    name: "John",
    email: "[email protected]",
    appointment_date: tomorrow,
    appointment_category: 3,
    time: "morning"
  }, {
    id: 35,
    name: "John",
    email: "[email protected]",
    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: "[email protected]",
    appointment_date: tomorrow,
    appointment_category: 5,
    time: "morning"
  }]
]

我们想要分离内部数组,并使一个变量保持所有单个约会,另一个变量保存所有多个约会。 JavaScript有一个内置的方法来处理像这样的数组filter。 Filter采用“tester”函数并将其应用于数组中的每个对象,并返回一个新数组,其中包含测试人员返回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: "[email protected]",
    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: "[email protected]",
  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: "[email protected]",
  appointment_date: tomorrow,
  appointment_category: 3,
  time: "morning"
}, {
  id: 35,
  name: "John",
  email: "[email protected]",
  appointment_date: tomorrow,
  appointment_category: 4,
  time: "afternoon"
}]

并返回如下对象:

{
  ids:[23, 35],
  name: John,
  email: [email protected],
  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.
}

0
投票

首先告诉您存储此数据的位置。 MongoDB的? MySQL的?记忆?

然后改变思维方式。您需要知道的是,您发送的电子邮件超过1个通知,而不是谁有多少次会议。而不是2个一维表,我建议你一个多维:

mails: {
 '[email protected]': [
{
        id: 23,
        name: "John",
        email: "[email protected]",
        appointment_date: tomorrow,
        appointment_category: 3,
        time: "morning"
    },  {
        id: 35,
        name: "John",
        email: "[email protected]",
        appointment_date: tomorrow,
        appointment_category: 4,
        time: "afternoon"
    }
]
'[email protected]': [{
        id: 17,
        name: "Alex",
        email: "[email protected]",
        appointment_date: tomorrow,
        appointment_category: 3,
        time: "morning"
    }
]
'[email protected]': [{
        id: 22,
        name: "Bob",
        email: "[email protected]",
        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])
© www.soinside.com 2019 - 2024. All rights reserved.