I am trying to calculate the occurrences of an Item in a list using LINQ,
I have the following schema -
User (All Entries Provided), Count (To be Calculated)
The count should be like -
I cannot think of an elegant solution to this.
Is it even possible only using LINQ? If not, how can we achieve this using LINQ with some C# Code.
You can do that with a combination of loop and Enumerable.Take
, Something like:
for (int i = 0; i < list.Count; i++)
{
//Get count of current element to before:
int count = list.Take(i+1)
.Count(r => r.UserName == list[i].UserName);
list[i].Count = count;
}
Where your list
is defined as:
List<User> list = new List<User>
{
new User{UserName = "A"},
new User{UserName = "B"},
new User{UserName = "A"},
new User{UserName = "A"},
new User{UserName = "B"},
new User{UserName = "A"},
new User{UserName = "C"},
new User{UserName = "A"},
};
and User
class as:
public class User
{
public string UserName { get; set; }
public int Count { get; set; }
}
Later you can print the output like:
foreach (var item in list)
{
Console.WriteLine("UserName: {0}, Running Total: {1}", item.UserName, item.Count);
}
and you will get:
UserName: A, Running Total: 1
UserName: B, Running Total: 1
UserName: A, Running Total: 2
UserName: A, Running Total: 3
UserName: B, Running Total: 2
UserName: A, Running Total: 4
UserName: C, Running Total: 1
UserName: A, Running Total: 5
Can it be done with LINQ? Probably not easily. Can it be done with your own extension method fairly easily? Sure (I haven't actually tried to compile and run the code so I can't guarantee that it'll work, but it's definitely a good starting point):
public static IEnumerable<Tuple<T, int>> RunningTotal<T>(this IEnumerable<T> source)
{
var counter = new Dictionary<T, int>();
foreach(var s in source)
{
if(counter.ContainsKey(s))
{
counter[s]++;
}
else
{
counter.Add(s, 1);
}
yield return Tuple.Create(s, counter[s]);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With