groupBy 和 sortBy 原生 ES6 中的对象数组
groupBy and sortBy an array of object in native ES6
我们有一个对象数组,我们需要按组 ID 对这些对象进行分组。
然后我们需要获取一个按时间戳排序的数组数组。
这是初始合集:
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;
}, {});
}
但是我们得到了一个无法排序的对象。所以我们需要将其转换为数组的数组,但我们很难做到这一点,然后对时间戳值进行排序。
您可以使用 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);
这是在 ES6 中使用 Map object and reduce 的另一行实现:
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)
我们有一个对象数组,我们需要按组 ID 对这些对象进行分组。
然后我们需要获取一个按时间戳排序的数组数组。
这是初始合集:
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;
}, {});
}
但是我们得到了一个无法排序的对象。所以我们需要将其转换为数组的数组,但我们很难做到这一点,然后对时间戳值进行排序。
您可以使用 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);
这是在 ES6 中使用 Map object and reduce 的另一行实现:
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)