Accepted answer

I would use the linq .Count() extension, which will count the number of items that satisfy a condition. Yes, this will iterate the list more times than is necessary, but it doesn't create any unnecessary objects, and it is very readable:

var countOccurences = new List<int>();
foreach (var inA in listA)
    countOccurences.Add(listB.Count(inB => inB == inA));
Console.WriteLine(string.Join(", ", countOccurences));

Once you've got the loop working, then it should be easy to see that it can be done in a single statement:

var countOccurences = listA.Select(inA => listB.Count(inB => inA == inB));


It's a good problem to use left outer join in LINQ. Here is an article about it. It's the best performance solution because you iterate over the collection just once and it's important for big collections or frequently used methods.

Here is an example for your problem:

var result = from a in listA
    join b in listB.GroupBy(x => x) on a equals b.Key into gj
    from subList in gj.DefaultIfEmpty()
    select new
        Number = a,
        Count = subList?.Count() ?? 0

You can also use GroupJoin and method chaining but I think that it's much harder to read:

var result = listA
    .GroupJoin(listB.GroupBy(x => x), a => a, b => b.Key, (a, gj) => new { a, gj })
    .SelectMany(@t => @t.gj.DefaultIfEmpty(), (@t, subList) => new { Number = @t.a, Count = subList?.Count() ?? 0 });

After that result will contains a collection of anonymous types with fields Number and Count with 3 elements: {1, 3}, {2, 4}, {8, 0}.

Update from comments (thanks to Caius Jard): if you can't use Null-Conditional Operator you may just replace it with explicit check: subList == null ? 0 : subList.Count()


fixing your code

var result = listB.GroupBy(x => x).ToDictionary(k => k.Key, v => v.Count());
foreach(var ent in listA)


one line Linq statment

listA.Select(a => listB.Contains(a) ? a : 0 ).Select(r=>listB.Count(w=> w==r)).ToList();

Related Articles