Построение словаря количества элементов в списке - PullRequest
9 голосов
/ 26 марта 2009

У меня есть список, содержащий несколько строк, которые могут встречаться более одного раза. Я хотел бы взять этот список и построить словарь элементов списка в качестве ключа и счетчик их вхождений в качестве значения.

Пример:

List<string> stuff = new List<string>();
stuff.Add( "Peanut Butter" );
stuff.Add( "Jam" );
stuff.Add( "Food" );
stuff.Add( "Snacks" );
stuff.Add( "Philosophy" );
stuff.Add( "Peanut Butter" );
stuff.Add( "Jam" );
stuff.Add( "Food" );

и результатом будет словарь, содержащий:

"Peanut Butter", 2
"Jam", 2
"Food", 2
"Snacks", 1
"Philosophy", 1

У меня есть способ сделать это, но не похоже, что я использую хорошие вещи в C # 3.0

public Dictionary<string, int> CountStuff( IList<string> stuffList )
{
    Dictionary<string, int> stuffCount = new Dictionary<string, int>();

    foreach (string stuff in stuffList) {
        //initialize or increment the count for this item
        if (stuffCount.ContainsKey( stuff )) {
            stuffCount[stuff]++;
        } else {
            stuffCount.Add( stuff, 1 );
        }
    }

    return stuffCount;
}

Ответы [ 5 ]

24 голосов
/ 26 марта 2009

Вы можете использовать предложение группы в C # для этого.

List<string> stuff = new List<string>();
...

var groups = from s in stuff group s by s into g select 
    new { Stuff = g.Key, Count = g.Count() };

Вы также можете вызывать методы расширения напрямую, если хотите:

var groups = stuff.GroupBy(s => s).Select(
    s => new { Stuff = s.Key, Count = s.Count() });

Отсюда короткий прыжок, чтобы поместить его в Dictionary<string, int>:

var dictionary = groups.ToDictionary(g => g.Stuff, g => g.Count);
8 голосов
/ 26 марта 2009

Я бы создал специализированный список, поддерживаемый словарем, а метод add проверил бы членство и увеличил бы количество, если он был найден.

Сорта, как:

public class CountingList
{
    Dictionary<string, int> countingList = new Dictionary<string, int>();

   void Add( string s )
   {
        if( countingList.ContainsKey( s ))
             countingList[ s ] ++;
        else
            countingList.Add( s, 1 );
   }
}
1 голос
/ 26 марта 2009

Одной из идей было бы присвоить словарю значение по умолчанию , равное нулю, чтобы вам не пришлось специально осматривать первое вхождение.

0 голосов
/ 01 сентября 2018
Dictionary<string, int> a = stuff.GroupBy(p => p).OrderByDescending(r=>r.Count()).ToDictionary(q => q.Key, q => q.Count());

Вы можете GroupBy, а затем создать словарь для подсчета каждой группы. Как показывает тест производительности , обычно существуют более эффективные подходы, кроме Linq Я думаю, ваш код более эффективен, а решение Linq более читабельно и красиво.

0 голосов
/ 26 марта 2009

Ну, нет лучшего способа сделать это.

Возможно, вы могли бы написать запрос LINQ, который бы сгруппировал строки и затем посчитал, сколько строк в каждой группе, но это было бы не так эффективно, как у вас уже есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...