【问题标题】:How to group text in messages?如何对消息中的文本进行分组?
【发布时间】:2019-11-15 23:55:34
【问题描述】:

美好的一天! 我有一个聊天,сhat 有一系列消息。

[{"id":4,
"user_id":1,
"messageable_id":3,
"messageable_type":"conversation",
"text":"Text 1",
"action":null,
"target_id":null,
"created_at":"2019-06-17 15:47:55",
"updated_at":"2019-06-17 15:47:55",
"replies":[],
"files":[]},

{"id":5,
"user_id":1,
"messageable_id":3,
"messageable_type":"conversation",
"text":"Text 2",
"action":null,
"target_id":null,
"created_at":"2019-06-17 15:48:00",
"updated_at":"2019-06-17 15:48:00",
"replies":[],
"files":[]}]

如果时差小于 60 秒,我想将消息文本合并到一条消息中

[{"id":4,
"user_id":1,
"messageable_id":3,
"messageable_type":"conversation",
"grouped_text":["Text 1","Text 2"], //GROUP 
"action":null,
"target_id":null,
"created_at":"2019-06-17 15:47:55",
"updated_at":"2019-06-17 15:47:55",
"replies":[],
"files":[]}]

我试试这个代码

let messages = this.$store.getters['conversation/messages'](this.conversation);
let grouped = _.groupBy(messages, message => {
    return this.$moment(message.created_at).startOf('minute');
});

我怎样才能做得更好?我可以使用 lodash

提前谢谢你

【问题讨论】:

  • 请添加您尝试过的代码
  • 我只是试试 lodash 函数 GroupBy 和 moment

标签: javascript arrays vue.js lodash javascript-objects


【解决方案1】:

lodash 的groupBy-function 不是用于此目的的正确工具。 groupBy-function 会将与键匹配的所有消息对象(在您的情况下,是同一分钟内的所有消息)放入一个数组中。

您可以使用reduce-函数。假设messages(您的问题中提到的消息)按日期排序:

const messages=[{"id":4,"user_id":1,"messageable_id":3,"messageable_type":"conversation","text":"Text 1","action":null,"target_id":null,"created_at":"2019-06-17 15:47:55","updated_at":"2019-06-17 15:47:55","replies":[],"files":[]},{"id":5,"user_id":1,"messageable_id":3,"messageable_type":"conversation","text":"Text 2","action":null,"target_id":null,"created_at":"2019-06-17 15:48:00","updated_at":"2019-06-17 15:48:00","replies":[],"files":[]}];

const result = messages.reduce((result, message) => {
    const lastMessage = result[result.length - 1];
    if (!lastMessage || new Date(message.created_at) - new Date(lastMessage.created_at) >= 60000) {
        message.grouped_text = [message.text]
        delete message.text;
        result.push(message);
    } else {
        lastMessage.grouped_text.push(message.text);
    }
    return result;
}, []);

console.log(result);

【讨论】:

    【解决方案2】:

    您可以使用reduce。如果上一条消息的created_at和当前消息的created_at相差小于1分钟(或60,000ms),则将消息推送到累加器中最后一条的grouped_text。否则,使用 grouped_text 属性将新消息推送到累加器

    您可以destructure每条消息分别获取text和rest的属性

    const messages=[{"id":4,"user_id":1,"messageable_id":3,"messageable_type":"conversation","text":"Text 1","action":null,"target_id":null,"created_at":"2019-06-17 15:47:55","updated_at":"2019-06-17 15:47:55","replies":[],"files":[]},{"id":5,"user_id":1,"messageable_id":3,"messageable_type":"conversation","text":"Text 2","action":null,"target_id":null,"created_at":"2019-06-17 15:48:00","updated_at":"2019-06-17 15:48:00","replies":[],"files":[]}]
    
    const groupDates = (date1, date2) => (new Date(date1) - new Date(date2) < 60000)
    
    const grouped = messages.reduce((r, { text, ...rest }, i, arr) => {
      const prev = arr[i - 1];
    
      if (prev && groupDates(rest.created_at, prev.created_at))
        r[r.length - 1].grouped_text.push(text)
      else
        r.push({ ...rest, grouped_text: [text] })
    
      return r;
    }, [])
    
    console.log(grouped)

    注意:这里假设消息是按照created_at排序的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多