linq.js 按 javascript 中的对象数组进行分组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23705077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
linq.js to group by array of objects in javascript
提问by user40721
I want to use linq.js to group the following data by date.
我想使用 linq.js 按日期对以下数据进行分组。
data2 = [{
"date": 1399298400.0,
"adId": 1057946139383,
"impressions": 1000000
}, {
"date": 1399298400.0,
"adId": 3301784671323,
"impressions": 535714
}...... etc.
];
Here's my attempt:
这是我的尝试:
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();
However, It's not working correctly because the sum of all the impressions
before and after the GroupBy
are close but not identical.
但是,它无法正常工作,因为所有impressions
前后的总和GroupBy
接近但不相同。
What is the correct way to use group by in linq.js in this case?
在这种情况下,在 linq.js 中使用 group by 的正确方法是什么?
Here's an example in fiddlewith full dataset here which alerts the total impressions before and after using the GroupBy
.
回答by KyleMit
Solution
解决方案
You can do this by passing a callback as the third parameter like this:
您可以通过将回调作为第三个参数传递来做到这一点,如下所示:
var grouped = Enumerable.from(dataArray).groupBy("$.person", null, (key, g) => {
return {
person: key,
likes: g.sum("$.likes | 0")
}
}).toArray()
Explanation
解释
In groupBy
, the third parameter allows you to modify the results before emitting:
在 中groupBy
,第三个参数允许您在发射前修改结果:
In JS, the bitwise or operator(a single pipe |
) returns the first value if it exists, otherwise it returns the second one. Without it, trying to sum an undefined value with a real one, will return NaN
在 JS 中,按位或运算符(单个管道|
)如果存在则返回第一个值,否则返回第二个值。没有它,尝试将未定义的值与真实值相加,将返回NaN
undefined + 1 // NaN
Without | 0
, the result would look like this:
如果没有| 0
,结果将如下所示:
This example uses shorthand syntax, but if you prefer anytime you see a string with a dollar sign, you can replace it with the lambda syntax like this (they both do the same exact thing):
这个例子使用速记语法,但如果你喜欢任何时候看到一个带有美元符号的字符串,你可以用这样的 lambda 语法替换它(它们都做完全相同的事情):
// Shorthand
.Select("$.impressions")
// Lambda
.Select(function (x) { return x.impressions })
Working demo with Stack Snippets:
使用 Stack Snippets 的工作演示:
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/[email protected]/linq.js"></script>
Further Reading:
进一步阅读:
回答by NYTom
I am the author of the open source project http://www.jinqJs.com. You can easily do that in jinqJs like this:
我是开源项目http://www.jinqJs.com 的作者。您可以像这样在 jinqJs 中轻松做到这一点:
jinqJs().from(data2).groupBy('date').sum('impressions').select();
Let me know if I can be of anymore help.
如果我能帮上忙,请告诉我。
回答by michal.jakubeczy
You might try to group by date.toString(). Might be safer due to how JS evaluates dates equality
您可以尝试按 date.toString() 分组。由于 JS 如何评估日期相等性,可能更安全
回答by KyleMit
Alternatively, people coming into this question might have zero to a lot of buy in using linq.js.
或者,遇到这个问题的人可能对使用 linq.js 的看法从零到很多。
If you're already pulling it in, go for it, but if this is the first couple real use cases for it, it's worth noting that you can accomplish the same thing in vanilla js:
如果您已经开始使用它,那就去做吧,但如果这是它的前几个真正用例,值得注意的是,您可以在vanilla js 中完成同样的事情:
For this data:
对于此数据:
var dataArray = [
{ person: "james", likes: 100 },
{ person: "james", likes: 250 },
{ person: "kyle", likes: 300 },
{ person: "kyle" }
];
You can build an object with properties for each key / person and keep summing the values of those props
您可以为每个键/人构建一个具有属性的对象,并不断总结这些道具的值
var obj = dataArray.reduce((acc, cur) => {
acc[cur.person] = (acc[cur.person] || 0) + (cur.likes || 0)
return acc
}, {})
If you want that to be an array of objects, you can convert from an object to array like this
如果你希望它是一个对象数组,你可以像这样从一个对象转换为数组
var array = Object.entries(obj).map(entry => {
return { person: entry[0], likes: entry[1] }
})