【问题标题】:Trying to group an array of objects under same keys resulting in a new array of objects尝试将一组对象分组在相同的键下,从而产生一个新的对象数组
【发布时间】:2020-02-16 07:40:43
【问题描述】:

我有一个由对象组成的messages 数组,其中每个对象代表一条消息,created_at 键代表消息的日期。我正在从 API 接收这些数据。这是我得到的结构:

let messages = [
  {text: "A", status: 'r', created_at: "2020-02-06"},
  {text: "B", status: 's', created_at: "2020-02-06"},
  {text: "C", status: 'r', created_at: "2020-02-06"},
  {text: "D", status: 's', created_at: "2020-02-07"},
  {text: "E", status: 's', created_at: "2020-02-07"},
  {text: "F", status: 'r', created_at: "2020-02-09"},
  {text: "G", status: 's', created_at: "2020-02-09"},
  {text: "H", status: 's', created_at: "2020-02-10"}
]

我正在使用vuejs 在聊天应用程序(类似于 WhatsApp)中呈现这些消息,我想在其中按时间顺序显示日期和该日期下的消息,就像 WhatsApp 一样。我按时间顺序从 API 接收消息,就像我在上面粘贴的 messages 数组一样。 我想得到以下输出,这样我就可以在vuejs 中使用v-for directive 循环遍历messages 并根据它们的创建日期呈现它们:

  output:
    [
      {
        dt: "2020-02-06",
        arr: [
            {text: "A", status: 'r', created_at: "2020-02-06"},
            {text: "B", status: 's', created_at: "2020-02-06"},
            {text: "C", status: 'r', created_at: "2020-02-06"},
        ]
      },
      {
        dt: "2020-02-07",
        arr: [
            {text: "D", status: 's', created_at: "2020-02-06"},
            {text: "E", status: 's', created_at: "2020-02-06"},
        ]
      },
      {
        dt: "2020-02-09",
        arr: [
            {text: "F", status: 'r', created_at: "2020-02-09"},
            {text: "G", status: 's', created_at: "2020-02-09"},
        ]
      },
        {
        dt: "2020-02-10",
        arr: [
           {text: "H", status: 's', created_at: "2020-02-10"}
        ]
      },
    ]

lodash中有没有可以直接实现这个的库?

到目前为止我所尝试的:

我能够在不重复日期的情况下将日期分组到一个数组中,如下所示:

let dates = messages.map((item => {
    return item.created_at
}))
let uniq = [...new Set(dates)];
console.log(uniq)

...给出以下输出:

uniq = ["2020-02-06", "2020-02-07", "2020-02-09", "2020-02-10"]

我无法继续前进。

提前致谢!

【问题讨论】:

    标签: javascript arrays lodash javascript-objects


    【解决方案1】:

    使用lodash按created_at分组,然后映射到需要的格式:

    const messages = [
      {text: "A", status: 'r', created_at: "2020-02-06"},
      {text: "B", status: 's', created_at: "2020-02-06"},
      {text: "C", status: 'r', created_at: "2020-02-06"},
      {text: "D", status: 's', created_at: "2020-02-07"},
      {text: "E", status: 's', created_at: "2020-02-07"},
      {text: "F", status: 'r', created_at: "2020-02-09"},
      {text: "G", status: 's', created_at: "2020-02-09"},
      {text: "H", status: 's', created_at: "2020-02-10"}
    ]
    
    const result = _.map(
      _.groupBy(messages, 'created_at'),
      (arr, dt) => ({ dt, arr })
    )
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

    【讨论】:

      【解决方案2】:

      如果您不需要,则无需大型库 - 遍历数组并将其组织成一个对象,其中键是日期,值是每个日期的数组。然后将对象的条目映射成对象数组:

      let messages = [
        {text: "A", status: 'r', created_at: "2020-02-06"},
        {text: "B", status: 's', created_at: "2020-02-06"},
        {text: "C", status: 'r', created_at: "2020-02-06"},
        {text: "D", status: 's', created_at: "2020-02-07"},
        {text: "E", status: 's', created_at: "2020-02-07"},
        {text: "F", status: 'r', created_at: "2020-02-09"},
        {text: "G", status: 's', created_at: "2020-02-09"},
        {text: "H", status: 's', created_at: "2020-02-10"}
      ];
      const messagesByDate = {};
      for (const message of messages) {
        if (!messagesByDate[message.created_at]) {
          messagesByDate[message.created_at] = [];
        }
        messagesByDate[message.created_at].push(message);
      }
      const output = Object.entries(messagesByDate).map(([dt, arr]) => ({ dt, arr }));
      console.log(output);

      【讨论】:

        【解决方案3】:

        使用reduce 构建对象并获取Object.values 将简化。

        const update = data => {
          return Object.values(
            data.reduce((acc, curr) => {
              const dt = curr.created_at;
              acc[dt] =
                dt in acc
                  ? { dt, arr: [...acc[dt].arr, { ...curr }] }
                  : { dt, arr: [{ ...curr }] };
              return acc;
            }, {})
          );
        };
        
        let messages = [
          { text: "A", status: "r", created_at: "2020-02-06" },
          { text: "B", status: "s", created_at: "2020-02-06" },
          { text: "C", status: "r", created_at: "2020-02-06" },
          { text: "D", status: "s", created_at: "2020-02-07" },
          { text: "E", status: "s", created_at: "2020-02-07" },
          { text: "F", status: "r", created_at: "2020-02-09" },
          { text: "G", status: "s", created_at: "2020-02-09" },
          { text: "H", status: "s", created_at: "2020-02-10" }
        ];
        
        console.log(update(messages));

        【讨论】:

        • 这是一个非常好的解决方案,代码行数最少。谢谢!!
        【解决方案4】:

        我在不使用任何外部库的情况下找到了解决方案:

        const messages = [
          {text: "A", status: 'r', created_at: "2020-02-06"},
          {text: "B", status: 's', created_at: "2020-02-06"},
          {text: "C", status: 'r', created_at: "2020-02-06"},
          {text: "D", status: 's', created_at: "2020-02-07"},
          {text: "E", status: 's', created_at: "2020-02-07"},
          {text: "F", status: 'r', created_at: "2020-02-09"},
          {text: "G", status: 's', created_at: "2020-02-09"},
          {text: "H", status: 's', created_at: "2020-02-10"}
        ]
        
        let dupDates = messages.map((item => {
        	return item.created_at
        }))
        let uniq = [...new Set(dupDates)];
        let grouping = uniq.map(uniqItem => {
        	let ret = messages.filter(msg => {
          	return msg.created_at === uniqItem
          })
          return {
          	 dt: uniqItem,
                 arr: ret
          }
        })
        console.log(grouping)
         

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-22
          • 2023-01-08
          相关资源
          最近更新 更多