Группировать одни и те же элементы в массиве JS, но только при последовательном - PullRequest
0 голосов
/ 18 ноября 2018

У меня есть массив объектов, представляющих серию «сообщений» в чате.Я хочу сгруппировать сообщения, которые последовательно создаются одним и тем же «пользователем», который хранится в каждом элементе массива.Вот упрощенная версия того, что я пытаюсь сделать:

[
    { message: "One", user: "Bob" },
    { message: "Two", user: "Bob" },
    { message: "Three", user: "Bob" },
    { message: "Hello", user: "Sam" },
    { message: "Hello", user: "Bob" },
    { message: "Hello", user: "Sam" },
    { message: "Hello", user: "Sam" }
]

должно быть превращено в:

[
    [
        { message: "One", user: "Bob"},
        { message: "Two", user: "Bob" },
        { message: "Three", user: "Bob" }
    ],
    [
        { message: "Hello", user: "Sam" }
    ],
    [
        { message: "Hello", user: "Bob" }
    ],
    [
        { message: "Hello", user: "Sam" },
        { message: "Hello", user: "Sam" }
    ]
]

Есть ли простой способ сделать это?Я нигде не смог найти ответ / алгоритм.

Ответы [ 4 ]

0 голосов
/ 18 ноября 2018

Вы можете решить это с помощью Array.reduce и используя его параметры для index массива и actual array:

const data = [{ message: "One", user: "Bob" }, { message: "Two", user: "Bob" }, { message: "Three", user: "Bob" }, { message: "Hello", user: "Sam" }, { message: "Hello", user: "Bob" }, { message: "Hello", user: "Sam" }, { message: "Hello", user: "Sam" } ]

const group = d => d.reduce((r,c,i,a) => (a[i].user == (a[i-1] && a[i-1].user) 
 ? r[r.length-1].push(c) : r.push([c]), r), [])

console.log(Object.values(group(data)))
0 голосов
/ 18 ноября 2018

Вы можете проверить последний элемент и, если у него нет того же пользователя, создать новый массив.

var data = [{ message: "One", user: "Bob" }, { message: "Two", user: "Bob" }, { message: "Three", user: "Bob" }, { message: "Hello", user: "Sam" }, { message: "Hello", user: "Bob" }, { message: "Hello", user: "Sam" }, { message: "Hello", user: "Sam" }],
    grouped = data.reduce((r, o, i, a) => {
        if (!i || a[i - 1].user !== o.user) {
            r.push([]);
        }
        r[r.length - 1].push(o);
        return r;
    }, []);
    
console.log(grouped);
0 голосов
/ 18 ноября 2018

Вы можете сделать это с помощью метода reduce.

const data = [
  { message: "One", user: "Bob" },
  { message: "Two", user: "Bob" },
  { message: "Three", user: "Bob" },
  { message: "Hello", user: "Sam" },
  { message: "Hello", user: "Bob" },
  { message: "Hello", user: "Sam" },
  { message: "Hello", user: "Sam" }
];

const result = data.reduce((acc, value) => {
  // compare the current value with the last item in the collected array
  if (acc.length && acc[acc.length - 1][0].user == value.user) {
    // append the current value to it if it is matching
    acc[acc.length - 1].push(value);
  } else {
    // append a new array with only the current value at the end of the collected array
    acc.push([value]);
  }

  return acc;
}, []);
  
console.log(result);
0 голосов
/ 18 ноября 2018

Вы можете сделать что-то вроде этого:

const messages = [
    { message: "One", user: "Bob" },
    { message: "Two", user: "Bob" },
    { message: "Three", user: "Bob" },
    { message: "Hello", user: "Sam" },
    { message: "Hello", user: "Bob" },
    { message: "Hello", user: "Sam" },
    { message: "Hello", user: "Sam" }
]

let currentUser;
let groupedMessages = [];

for (message of messages) {

  if (message.user !== currentUser) {
    groupedMessages.push([]);
    currentUser = message.user;
  }
  groupedMessages[groupedMessages.length - 1].push(message)
}

console.log(groupedMessages);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...