groupBy и sortBy массив объектов в нативном ES6 - PullRequest
0 голосов
/ 12 октября 2018

У нас есть массив объектов, и нам нужно сгруппировать эти объекты по идентификатору группы.

Затем нам нужно получить массив массивов с отсортированными группами по отметке времени.

Этоначальная коллекция:

const arr = [
  {id: 'id1', group: '123', timestamp: 222},
  {id: 'id2', group: '123', timestamp: 999 },
  {id: 'id3', group: '456', timestamp: 333 },
  {id: 'id4', group: '789', timestamp: 111 },
  {id: 'id5', group: '554', timestamp: 555 },
];

Результат, который мы пытаемся получить:

result = [
  [
    {id: 'id4', group: '789', timestamp: 111 }, 
  ],
  [
    {id: 'id1', group: '123', timestamp: 222},
    {id: 'id2', group: '123', timestamp: 999 },
  ],
  [
    {id: 'id3', group: '456', timestamp: 333 },
  ],
  [
    {id: 'id5', group: '554', timestamp: 555 },
  ]
]

Мы достигли этого с помощью Underscore.js, но мы ищем решение с использованием собственного javascript, и мы изо всех сил пыталисьперейти от сокращенного объекта к массиву массива.

var groups = _(arr).chain()
    .groupBy("group")
    .sortBy((data) => _.first(data).timestamp)
    .value();

https://jsfiddle.net/tdsow1ph/

Мы попытались сначала сгруппировать элементы, используя такой метод:

const groupBy = (arr, propertyToGroupBy) => {
    return arr.reduce((groups, item) => {
      const val = item[propertyToGroupBy];

      groups[val] = groups[val] || [];
      groups[val].push(item);

      return groups;
    }, {});
  }

Но мы получаем несортируемый объект.Поэтому нам нужно преобразовать это в массив массива, но мы изо всех сил пытаемся это сделать, а затем применяем сортировку по значению временной метки.

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Вот еще одна однострочная реализация в ES6 с использованием объекта карты и сокращение :

const arr = [ {id: 'id1', group: '123', timestamp: 222}, {id: 'id2', group: '123', timestamp: 999 }, {id: 'id3', group: '456', timestamp: 333 }, {id: 'id4', group: '789', timestamp: 111 }, {id: 'id5', group: '554', timestamp: 555 }, ];

const result = [...arr.reduce((r,c) => (r.set(c.group, r.has(c.group) ? 
  [...r.get(c.group), c] : [c]), r), new Map()).values()]

console.log(result)

Для сортировки просто префикс, который уменьшается с начальным sort:

const arr = [ {id: 'id1', group: '123', timestamp: 222}, {id: 'id2', group: '123', timestamp: 999 }, {id: 'id3', group: '456', timestamp: 333 }, {id: 'id4', group: '789', timestamp: 111 }, {id: 'id5', group: '554', timestamp: 555 }, ];

const result = [...arr.sort((a,b) => a.timestamp - b.timestamp)
   .reduce((r,c) => (r.set(c.group, r.has(c.group) ? 
   [...r.get(c.group), c] : [c]), r), new Map()).values()]

console.log(result)
0 голосов
/ 12 октября 2018

Вы можете использовать reduce() для группировки массива в объект, используя группу в качестве ключа.Используйте Object.values() для преобразования объекта в массив.

const arr = [{"id":"id1","group":"123","timestamp":222},{"id":"id2","group":"123","timestamp":999},{"id":"id3","group":"456","timestamp":333},{"id":"id4","group":"789","timestamp":111},{"id":"id5","group":"554","timestamp":555}];

var result = Object.values(arr.reduce((c, v) => {
  c[v.group] = c[v.group] || [];
  c[v.group].push(v);
  return c;
}, {}));


console.log(result);

С sort()

const arr = [{"id":"id4","group":"789","timestamp":111},{"id":"id1","group":"123","timestamp":222},{"id":"id3","group":"456","timestamp":333},{"id":"id5","group":"554","timestamp":555},{"id":"id2","group":"123","timestamp":999}]

var result = Object.values(
  arr
  .sort((a, b) => a.timestamp - b.timestamp)
  .reduce((c, v) => {
    c[v.group] = c[v.group] || [];
    c[v.group].push(v);
    return c;
  }, {})
);

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