List<object> li = new List<object>() {0,1,"текст 1",0,2,3,3.4,4,3,1,9,3.4,"1"};
foreach (var x in li.GroupBy(c => new { Name = c }).
Select( c => new { c.Key.Name, Count = c.Count() }))
{
Console.WriteLine($"{x.Name} содержится: {x.Count} {x.Name.GetType()}");
}
Здесь с помощью лямда выражений происходит поиск количества элементов в списке. Но я не понимаю как это работает.
Итак у вас есть коллекция объектов.
GroupBy в foreach формирует структуру IEnumerable<IGrouping<TKey, TElement>> в TKey в данном случае записывается экземпляр анонимного типа с единственным полем Name а во внутреннюю коллекцию частичного результата группировки IGrouping<TKey, TElement>.elements все копии объекта переданного в Name с типом TElement. В данном тип TElement это object.
Структура IEnumerable<IGrouping<TKey, TElement>> чем-то напоминает IEnumerable<KeyValuePair<TKey, List<TElement>>>, где TKey общий признак для группировки, а List все элементы удовлетворяющие признаку.
Затем вы делаете Select по этой структуре в которой пробегаете по всем KeyValuePair<TKey, List<TElement>> и создаете коллекцию экземпляров других анонимных типов которые содержат поля Name и Count в которые вы записываете сответственно (TKey).Name экземпляра первого анонимного типа и количество объектов в коллекции (List<TElement>).Count.
Затем эта коллекция анонимных экземпляров попадает в foreach в которой вы поочередно выводите .Name и .Count.
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости