我想使用linq.js按日期对以下数据进行分组。
data2 = [{
"date": 1399298400.0,
"adId": 1057946139383,
"impressions": 1000000
}, {
"date": 1399298400.0,
"adId": 3301784671323,
"impressions": 535714
}...... etc.
];
这是我的尝试:
var linq = Enumerable.From(data2);
data2 = linq.GroupBy(function (x) {
return x.date;
}).Select(function (x) {
return {
date: x.Key(),
impressions: x.Sum(function (y) {
return y.impressions | 0;
})
};
}).ToArray();
但是,它无法正常工作,因为impressions
之前和之后的所有GroupBy
的总和很接近但不相同。
在这种情况下,在linq.js中使用group by的正确方法是什么?
此处为an example in fiddle,其中包含完整数据集,用于提醒使用GroupBy
之前和之后的总展示次数。
答案 0 :(得分:7)
您可以通过将回调作为第三个参数传递来执行此操作:
var grouped = Enumerable.from(dataArray).groupBy("$.person", null, (key, g) => {
return {
person: key,
likes: g.sum("$.likes | 0")
}
}).toArray()
在groupBy
中,第三个参数允许您在发出之前修改结果:
在JS中,bitwise or operator(单个管道|
)返回第一个值(如果存在),否则返回第二个值。如果没有它,尝试将未定义的值与实数值相加,将返回NaN
undefined + 1 // NaN
如果没有| 0
,结果将如下所示:
此示例使用简写语法,但如果您喜欢在任何时候看到带有美元符号的字符串,您可以将其替换为这样的lambda语法(它们都做同样的事情):
// Shorthand
.Select("$.impressions")
// Lambda
.Select(function (x) { return x.impressions })
var dataArray = [
{
person: "james",
likes: 100
},
{
person: "james",
likes: 250
},
{
person: "kyle",
likes: 300
},
{
person: "kyle"
//,likes: 450
}
];
var grouped = Enumerable.from(dataArray).groupBy("$.person", null, (key, g) => {
return { person: key, likes: g.sum("$.likes | 0") }
}).toArray()
console.log(grouped);

<script src="https://unpkg.com/linq@3.2.0/linq.js"></script>
&#13;
答案 1 :(得分:3)
我是开源项目http://www.jinqJs.com的作者。您可以在jinqJs中轻松完成此操作:
jinqJs().from(data2).groupBy('date').sum('impressions').select();
如果我能帮助我,请告诉我。
答案 2 :(得分:0)
您可以尝试按date.toString()进行分组。由于JS如何评估dates equality
,可能会更安全答案 3 :(得分:0)
或者,使用linq.js的人可能对零钱有很大的兴趣。
如果已经投入使用,那就去做吧,但是如果这是它的头几个实际用例,则值得注意的是,您可以在 vanilla js 中完成相同的工作:
对于此数据:
var dataArray = [
{ person: "james", likes: 100 },
{ person: "james", likes: 250 },
{ person: "kyle", likes: 300 },
{ person: "kyle" }
];
您可以为每个键/人构建一个具有属性的对象,并不断求和这些道具的值
var obj = dataArray.reduce((acc, cur) => {
acc[cur.person] = (acc[cur.person] || 0) + (cur.likes || 0)
return acc
}, {})
如果您希望将其作为对象数组,则可以像这样从一个对象转换为数组
var array = Object.entries(obj).map(entry => {
return { person: entry[0], likes: entry[1] }
})