I have a function that's main goal to group items by id, count them and finally order them by count.
var Db = list.Select(x => new
{
Id = x
});
var groups = Db.GroupBy(g => new { Id = g.Id })
.Select(g => new
{
Id = g.Key.Id,
Cnt = g.Count()
}).Distinct().OrderBy(g => g.Cnt).ToList();
Do you have any idea, where the error might be? It is not ordering. I have a bunch of low counts at first then it becomes random.
'list' is a one-dimensional list with many duplicated Ids (string) .
This is the output its giving out: ( I do not understand why there's duplicates in the ID since I'm only grouping by one key).
Link to output : https://pastebin.com/NjqJ4Aub
Related
I have such a table as shown below
I need to group each record by LifePluseCaseId column,
and each group must be selected by Min distance and Min Duration
And return All of the fields.
I have tried this:
var query = db.ApplicantCenterDistance.GroupBy(s => s.LifeplusCaseId)
.Select(s => new {
Id = s.Key,
MinDistance = s.Min(m => m.Distance),
Duration = s.Min(m => m.Duration)
}).ToList();
But i don't know how to get all fields in Select statement and what the role of key is.
Is s.Key equals to s.LifeplusCaseId?
From the above queries, each group will have multiple ApplicantCenterDistances record (in theory) because... well it's a group. If you really want to get all the items in each group as well, you can do like this (pseudo-code):
var productByCategory = await db.Products
.GroupBy(q => q.CategoryId)
.Select(q => new {
CategoryId = q.Key,
// Here q is also acting as a list of products with the same `CategoryId`
Products = q,
// Or if you only want some specific fields
ProductCustoms = q.Select(p => new {
Name = p.Name,
Color = p.Color,
// All fields you want
})
}).ToListAsync(); // Do whatever you want with the result
Now it makes much more sense right? The productByCategory is a list of groups, each group has the key (CategoryId), and has a list of products that has that matching CategoryId.
I have a group of records that includes PatientID and Appointment Date.
I would like to group them by PatientID and order the groups by the oldest appointment in each PatientID group. Like this...
ID ApptDate
----------------------
3 2/5/2005 (oldest compared to all groups , so group "ID = 3" is sorted first)
3 5/10/2006
3 6/2/2010
1 8/5/2007
1 9/1/2015
2 6/15/2009
2 9/19/2009
I'm pretty sure I need to use grouping first to obtain the oldest date value for each ID and then order by that value but I am stuck understanding how the two functions will work together.
var query = from a in db.Appointments
group a by new { a.Id, a.ApptDate} into pa
select new {
ID = pa.Key.Id,
Date = pa.Min(x =>x.ApptDate) ...
... but I crash and burn at this point.
Any help appreciated.
I modified a bit Tanveer Badar's answer to return a row for each entity.
Create a class for your return data
public class ReturnType
{
public int ID { get; set; }
public DateTime AppDate { get; set; }
}
Get a group of IDs and enumerable of ordered dates
var result = db.Appointment
.GroupBy(a => a.Id)
.OrderBy(a => a.Min(n => n.Date))
.Select(a => new { ID = a.Key, AppDates = a.OrderBy(na =>
na.Date).Select(ne => ne.Date) })
.ToList();
Then flatten the returned list. I tried with SelectMany but with no success.
var results = new List<ReturnType>();
foreach (var a in result)
{
foreach (var date in a.AppDates)
{
var returnType = new ReturnType
{
ID = a.ID,
AppDate = date
};
results.Add(returnType);
}
}
You requirements are as follows (though the question does not mention one of them, but it is apparent from how data is laid out):
Group based on patient ID.
Sort groups based on oldest appointment date in each group.
Sort data within a group based on appointment date.
var query = records.GroupBy(r => r.PatientId) // Group patients
.OrderBy(g => g.Min(r => r.AppointmentDate)) // sort groups by oldest record in each
.Select(g =>
new
{
PatientId = g.Key,
Records = g.OrderBy(r => r.AppointmentDate) // sort records within a group by oldest
});
In my case it works fine...
var query = from a in db.Appointments
group a by new { a.Id, a.ApptDate} into pa
select new {
ID = pa.Key.Id,
Date = pa.Max(x =>x.ApptDate)
}).Select(x=>new {
x.ID,x.Date
}).ToList();
db.Appointments.GroupBy(new {ID = item.ID, ApptDate = item.ApptDate}).OrderByDescending(item => item.ApptDate)
I am having a bit of problem in that I am trying to GroupBy using linq and although it works, it only works when I eliminate one element of the code.
nestedGroupedStocks = stkPositions.GroupBy(x => new { x.stockName,
x.stockLongshort,x.stockIsin, x.stockPrice })
.Select(y => new stockPos
{
stockName = y.Key.stockName,
stockLongshort = y.Key.stockLongshort,
stockIsin = y.Key.stockIsin,
stockPrice = y.Key.stockPrice,
stockQuantity = y.Sum(x => x.stockQuantity)
}).ToList();
The above code Groups my stock positions and the results in the list containing 47 entries but what it fails to do is sum duplicate stocks with different quantities...
nestedGroupedStocks = stkPositions.GroupBy(x => new { x.stockName,
x.stockIsin, x.stockPrice })
.Select(y => new stockPos
{
stockName = y.Key.stockName,
stockIsin = y.Key.stockIsin,
stockPrice = y.Key.stockPrice,
stockQuantity = y.Sum(x => x.stockQuantity)
}).ToList();
However, if I elimanate "x.longshort" then I get the desired result, 34 stocks summed up, but the then all longshort elements in the list are null...
Its driving me nuts :-)
This part
.GroupBy(x => new { x.stockName,x.stockLongshort,x.stockIsin, x.stockPrice })
is the problem. You are trying to group the elements by that new object as key, but x.stockLongshort will most likely change for every single element in the list, making the GroupBy fail unless the name and the stockLongshort will match in both elements ( as for the other 2 fields, but I assume those are always the same).
nestedGroupedStocks = stkPositions.GroupBy(x => x.stockName)
.Select(y => new stockPos
{
stockName = y.First().stockName,
stockLongshort = y.First().stockLongshort,
stockIsin = y.First().stockIsin,
stockPrice = y.First().stockPrice,
stockQuantity = y.Sum(z => z.stockQuantity)
}).ToList();
Note that the stockLongshort property is set to be equal to the value of the first element in the group. You could set it to 0 if that's more usefull to you.
Longer Explanation
GroupBy returns IEnumerable<IGrouping<TKey, TSource>> , that is, a "set" (that you can enumarte) of Groups, with each element of the same group sharing the same Key, that you have defined with the lambda expression in the argument.
If you put x.stockLongshort as a property of the Key object, that becomes a discriminant of the evaluation made by GroupBy, that, as a consequence, puts two elements that differ just by that property in two distinct groups.
I have a class (ApplicationHistory) with 3 properties:
ApplicantId, ProviderId, ApplicationDate
I return the data from the database into a list, however this contains duplicate ApplicantId/ProviderId keys.
I want to supress the list so that the list only contains the the earliest Application Date for each ApplicantId/ProviderId.
The example below is where I'm currently at, but I'm not sure how to ensure the earliest date is returned.
var supressed = history
.GroupBy(x => new
{
ApplicantId = x.ApplicantId,
ProviderId = x.ProviderId
})
.First();
All advice appreciated.
Recall that each group formed by the GroupBy call is an IGrouping<ApplicationHistory>, which implements IEnumerable<ApplicationHistory>. Read more about IGrouping here. You can order those and pick the first one:
var oldestPerGroup = history
.GroupBy(x => new
{
ApplicantId = x.ApplicantId,
ProviderId = x.ProviderId
})
.Select(g => g.OrderBy(x => x.ApplicationDate).FirstOrDefault());
You are selecting first group. Instead select first item from each group:
var supressed = history
.GroupBy(x => new {
ApplicantId = x.ApplicantId,
ProviderId = x.ProviderId
})
.Select(g => g.OrderBy(x => x.ApplicationDate).First());
Or query syntax (btw you don't need to specify names for anonymous object properties in this case):
var supressed = from h in history
group h by new {
h.ApplicantId,
h.ProviderId
} into g
select g.OrderBy(x => x.ApplicationDate).First();
I have a (C#) class called Hit with an ItemID (int) and a Score (int) property. I skip the rest of the details to keep it short. Now in my code, I have a huge List on which I need to do the following select (into a new List): I need to get the sum of all Hit.Score's for each individual Hit.ItemID, ordered by Score. So if I have the following items in the original list
ItemID=3, Score=5
ItemID=1, Score=5
ItemID=2, Score=5
ItemID=3, Score=1
ItemID=1, Score=8
ItemID=2, Score=10
the resulting List should contain the following:
ItemID=2, Score=15
ItemID=1, Score=13
ItemID=3, Score=6
Can somebody help?
var q = (from h in hits
group h by new { h.ItemID } into hh
select new {
hh.Key.ItemID,
Score = hh.Sum(s => s.Score)
}).OrderByDescending(i => i.Score);
IEnumerable<Hit> result = hits.
GroupBy(hit => hit.ItemID).
Select(group => new Hit
{
ItemID = group.Key,
Score = group.Sum(hit => hit.Score)
}).
OrderByDescending(hit => hit.Score);