我有这个对象数据:
[ RowDataPacket {
id: 59,
steamid: '76561198220437096',
product_id: 23,
status: 1,
date: 2017-12-18T17:27:19.000Z,
message: null,
name: 'CS.MONEY',
amount: 100,
website: 'csgo500' },
RowDataPacket {
id: 60,
steamid: '76561198220437096',
product_id: 24,
status: 1,
date: 2017-12-18T17:27:19.000Z,
message: null,
name: 'CS.MONEY',
amount: 250,
website: 'csgo500' },
RowDataPacket {
id: 61,
steamid: '76561198220437096',
product_id: 23,
status: 1,
date: 2017-12-18T17:27:19.000Z,
message: null,
name: 'CS.MONEY',
amount: 100,
website: 'csgo500' },
RowDataPacket {
id: 62,
steamid: '76561198345348530',
product_id: 6,
status: 1,
date: 2017-12-18T20:05:55.000Z,
message: null,
name: 'wal gruche',
amount: 100,
website: 'csgoatse' }
我试图用steamid和网站对这些数据进行排序,我设法只对这个值进行排序,如下所示:
var groupedOrders = {};
row.forEach(function(item){
var list = groupedOrders[item.steamid];
if(list){
list.push(item);
} else{
groupedOrders[item.steamid] = [item];
}
});
我的想法是制作二维数组但由于某种原因我不能这样做:
var list = groupedOrders[item.steamid][item.website];
它抛出一个错误“无法读取属性...未定义”
现在我的代码看起来像这样:
var groupedOrders = {};
row.forEach(function(item){
var list = groupedOrders[item.steamid][item.website];
if(list){
list.push(item);
} else{
groupedOrders[item.steamid][item.website] = [item];
}
});
您有任何想法如何解决此错误?
问题是var list = groupedOrders[item.steamid][item.website]
实际上在说:
var temp = groupedOrders[item.steamid];
var list = temp[item.website];
在groupedOrders[item.steamid]
没有进入,所以第一线将temp
设置为undefined
。第二行尝试索引到undefined
,这是一个错误。
您必须将代码拆分出来并基本上完成整个一键分组两次:
var outerList = groupedOrders[item.steamid];
if (!outerList)
outerList = groupedOrders[item.steamid] = {};
var innerList = outerList[item.website];
if (innerList)
innerList.push(item);
else
outerList[item.website] = [item];
(我没有测试过这段代码但它的形状是正确的。)
以下工作通过为作为参数提供的每个字段创建递归groupBy
分组函数。
然后逐个调用这些动态创建的groupBy
函数,从提供的数据开始传递结果。
每个groupBy
函数实例都会创建一个对象,并为其添加与要分组的字段的键值对应的属性。
通过连续调用这些groupBy
函数,我们创建了一个逐渐更多嵌套的对象树,每个连续级别的组使用符号标记为组。
最终结果是对象的嵌套(树!),其键对应于用于在该级别进行索引的字段。
最后,我们将巢展平,最终的顺序是可见的。
const flatten = o => Object.values(o).reduce((acc, c) => (Array.isArray(c) ? [...acc, ...c] : typeof c === 'object' ? [...acc, ...flatten(c)] : [...acc, c]), []);
const flow = (...fns) => data => fns.reduce((acc, c) => c(acc), data);
const GROUP = Symbol('group');
const asGroup = (result = []) => ((result[GROUP] = true), result);
const isGroup = o => o[GROUP];
const groupBy = field => (data, key) =>
data.reduce((acc, c) =>
((key = c[field]), (acc[key] ?
(acc[key].push(c), acc) :
((acc[key] = asGroup([c])), acc))), {});
const recurse = (test) => (transform) => o =>
test(o)
? transform(o)
: Object.entries(o).reduce(
(acc, [k, v]) => (test(v) ?
((acc[k] = transform(v)), acc) :
((acc[k] = recurse(test)(transform)(v)), acc)), {});
const group = (...fields) => flow(...fields.map(flow(groupBy, recurse(isGroup))), flatten);
const rows = asGroup([
{
id: 0,
steamid: '2',
website: 'a'
},
{
id: 1,
steamid: '2',
website: 'b'
},
{
id: 2,
steamid: '2',
website: 'a'
},
{
id: 3,
steamid: '1',
website: 'b'
},
{
id: 4,
steamid: '0',
website: 'b'
}
]);
console.log(JSON.stringify(group('steamid', 'website')(rows), null, 2));