Как сгруппировать текст в сообщениях? - PullRequest
1 голос
/ 05 июля 2019

Добрый день!У меня есть чат, и у него есть массивы сообщений.

[{"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

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 05 июля 2019

Функция lodash groupBy не подходит для этого. Функция groupBy помещает все объекты сообщений, которые соответствуют ключу (в вашем случае, все сообщения в течение одной минуты) в массив.

Вы можете использовать функцию 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);
0 голосов
/ 05 июля 2019

Вы можете использовать reduce. Если предыдущее сообщение created_at и разница текущего сообщения created_at меньше 1 минуты (или 60 000 мс), отправьте сообщение на grouped_text последнего элемента в аккумуляторе. В противном случае отправьте новое сообщение в аккумулятор со свойством grouped_text

.

Вы можете уничтожить каждое сообщение, чтобы получить 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

.
...