Reputation: 1328
I am wondering if/how I can do the following thing using LINQ: I have a list of objects with some properties and another list of different distinct values corresponding to a certain property.
Example:
A = [{id=1, property=1}, {id=2, property=1}, {id=3, property=2}]
B = [1, 2]
Is there a way of achieving the following thing (obtaining the counts list) using only LINQ?
var counts = new List<int>();
foreach (var b in B)
{
counts.Add(A.Where(a => a.property == b).Count();
}
Sample code:
public class MyObject
{
public MyObject(int id, int prop)
{
Id = id;
Property = prop;
}
public int Id { get; set; }
public int Property { get; set; }
public void test()
{
var A = new List<MyObject>
{
new MyObject(1, 1), new MyObject(2, 1), new MyObject(3, 2)
};
var B = new List<int>{1, 2};
// LINQ magic
// 2 objects with property 1
// 1 object with property 2
}
}
Upvotes: 0
Views: 5905
Reputation: 1224
This is the gist of what you need. I'm typing this without a c# compiler, so hopefully this doesn't have errors.
var results =
from a in A
join b in B on a.property equals b
group a by a.property into g
select new { Property = g.Key, Count = g.Count() }
Upvotes: 0
Reputation: 37020
Sure, you can just loop through the values and, for each one, get the count of items that have Property == value
.
In the sample below, I'm selecting an anonymous type that contains the Value
and the Count
of each item that has Property == value
:
public class Data
{
public int Id { get; set; }
public int Property { get; set; }
}
public class Program
{
private static void Main()
{
var allData = new List<Data>
{
new Data {Id = 1, Property = 1},
new Data {Id = 2, Property = 1},
new Data {Id = 3, Property = 2},
};
var values = new[] {1, 2};
var results = values.Select(value =>
new {Value = value, Count = allData.Count(item => item.Property == value)});
foreach (var result in results)
{
Console.WriteLine($"{result.Count} objects with Property {result.Value}");
}
}
}
Output
Upvotes: 1
Reputation: 3030
Yes, use select operators to only select the specific properties you want to compare, and then use intersect and count to get the count. Example:
var listOfObjects = new List<PocoClass>()
{
new PocoClass(){Id=1,Property=3},
new PocoClass(){Id=2,Property=2}
};
var intArray = new int[] { 1, 2, 3 };
var count = listOfObjects.Select(o => o.Property).Intersect(intArray).Count();
Upvotes: 2
Reputation: 7054
You can use Count
method with a predicate:
var A = new[] {new {id = 1, property = 1}, new {id = 2, property = 1}, new {id = 3, property = 2}};
var B = new[] {1, 2};
var count = B.Count(b => A.Any(a => a.property == b));
Code above will check every member in B
and if at least one member in A
have a property
with that value it will be counted
Upvotes: 1
Reputation: 177
convert B to List and run ForEach on it
B.OfType<int>().ToList().ForEach(m=>{
counts.Add(A.Where(a => a.property == m).Count();
})
Upvotes: 0