I have the following array:
var source = [
{ "DistributorId": 1, "DistributorName": "Distributor 01", "PriceListId": 1, "Year": 2014, "Month": 9 },
{ "DistributorId": 1, "DistributorName": "Distributor 01", "PriceListId": 2, "Year": 2014, "Month": 10 },
{ "DistributorId": 2, "DistributorName": "Distributor 02", "PriceListId": 3, "Year": 2014, "Month": 10 },
{ "DistributorId": 3, "DistributorName": "Distributor 03", "PriceListId": 4, "Year": 2014, "Month": 9 },
{ "DistributorId": 3, "DistributorName": "Distributor 03", "PriceListId": 5, "Year": 2014, "Month": 10 }
];
I want to to use linq.js to group these array by two fields "DistributorId" and "DistributorName" to get the following result:
var des =
[
{
"DistributorId": 1,
"DistributorName": "Distributor 01",
"PriceLists":
[
{ "Year": 2014, "Month": 9 },
{ "Year": 2014, "Month": 10 }
]
},
{
"DistributorId": 2,
"DistributorName": "Distributor 02",
"PriceLists":
[
{ "Year": 2014, "Month": 10 }
]
},
{
"DistributorId": 3,
"DistributorName": "Distributor 03",
"PriceLists":
[
{ "Year": 2014, "Month": 9 },
{ "Year": 2014, "Month": 10 }
]
}
];
The overload of group by that you want looks like this:
// Overload:function(keySelector,elementSelector,resultSelector,compareSelector)
First you'll need the key which is a combination of the distributor id and name. Then collect all years and months that have the same distributor id and name. The result of course and a way to compare the key objects (the properties as strings is a simple way to achieve that).
var query = Enumerable.from(data)
.groupBy(
"{ Id: $.DistributorId, Name: $.DistributorName }",
"{ Year: $.Year, Month: $.Month }",
"{ DistributorId: $.Id, DistributorName: $.Name, PriceLists: $$.toArray() }",
"String($.Id) + $.Name"
)
.toArray();
Just note that I'm using the linq.js 3.x names: methods using lowerCamelCase. Change to UpperCamelCase for older versions.