толковый словарьувеличить значение - PullRequest
4 голосов
/ 07 декабря 2011

У меня есть Dictionary<string, int>, и я читаю некоторые строки из списка ... Я хочу добавить их в словарь, но если строка уже есть в словаре, я хочу, чтобы ее значение увеличилось на 1.

Код, который я пробовал, приведен ниже, но есть некоторые строки, которые увеличиваются с каждым вводом. Что-то не так?

    Dictionary<string, int> dictionary = new Dictionary<string, int>();
    foreach (String recordline in tags)
    {
        String recordstag = recordline.Split('\t')[1];
        String tagToDic = recordstag.Substring(0, (recordstag.Length-1) );

        if (dictionary.ContainsKey(tagToDic) == false)
        {
            dictionary.Add(tagToDic, 1);
        }
        else
        {

            try
            {
                dictionary[tagToDic] = dictionary[tagToDic] + 1;
            }
            catch (KeyNotFoundException ex)
            {
                System.Console.WriteLine("X" + tagToDic + "X");
                dictionary.Add(tagToDic, 1);
            }
        }
    }

РЕДАКТИРОВАТЬ: Чтобы ответить на ваши комментарии ... Я удаляю последний символ строки, потому что это всегда пробел ... Мой вклад как:

10000301    business    0   0,000
10000301    management & auxiliary services     0   0,000
10000316    demographie     0   0,000
10000316    histoire de france  0   0,000
10000347    economics   0   0,000
10000347    philosophy   1   0,500

и мне нужна только строка типа "бизнес" или "управление и вспомогательные услуги" и т. Д.

Ответы [ 8 ]

6 голосов
/ 07 декабря 2011

Вы разбиваете каждую строку в массиве входных строк и выбираете 2-ю строку в массиве строк. Затем вы удаляете последний символ этой второй строки, используя SubString . Следовательно, все строки, которые отличаются только последним символом, будут считаться одинаковыми и увеличиваться. Вот почему вы можете видеть «некоторые строки, которые увеличиваются с каждым вводом».

РЕДАКТИРОВАТЬ: если целью удаления последнего символа является удаление пробела, используйте вместо него String.Trim. Другое редактирование использует TryGetValue вместо ContainsKey, который работает лучше для увеличения вашего значения. Код был отредактирован ниже.

Попробуйте это:

    Dictionary<string, int> dictionary = new Dictionary<string, int>();
    foreach(string recordline in tags) 
    {
       string recordstag = recordline.Split('\t')[1].Trim();
       int value;
       if (!dictionary.TryGetValue(recordstag, out value))
         dictionary.Add(recordstag, 1);
       else
         dictionary[recordstag] = value + 1;
    }
2 голосов
/ 07 декабря 2011

Нет необходимости в словаре, можно решить с помощью этого запроса Linq.
(Предполагая, что вам нужна полная строка после \t)

var q = 
    from s in tags.Select (t => t.Substring(t.IndexOf("\t")))
    group s by s into g
    select new
    {
        g.Key,
        Count = g.Count()
    };

А если вам нужен словарь,добавить:

var dic = q.ToDictionary (x => x.Key, x => x.Count);
1 голос
/ 07 декабря 2011

Ваша входная строка сначала split , а затем ее подстрока возвращена в tagToDic, так что, возможно, n строк имеют такой же tagToDic.

0 голосов
/ 17 ноября 2014

Метод расширения

public static void Increment(this Dictionary<string, int> dictionary, string key)
{
     int val;
     dictionary.TryGetValue(key, out val);
     if (val != null) 
         dictionary[key] = val + 1;
}

Dictionary<string, int> dictionary = new Dictionary<string, int>();
// fill with some data

dictionary.Increment("someKey");
0 голосов
/ 07 декабря 2011

Ваш код dictionary выглядит так, как будто он будет работать так, как вы ожидаете.

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

В любом случае, весь ваш блок кода может быть упрощен и переписан с помощью LINQ как:

var dictionary = tags
    .Select(t => {
        var recordstag = t.Split('\t')[1];
        return recordstag.Substring(0, recordstag.Length-1);
    })
    .GroupBy(t => t)
    .ToDictionary(k => k.Key, v => v.Count())
    ;
0 голосов
/ 07 декабря 2011

Если они есть в списке, вы можете просто сгруппировать их и составить список.

list.GroupBy(recordline => recordline.Split('\t').Substring(0, (recordstag.Length-1), 
    (key, ienum) => new {word = key, count = ienum.Count()});

Тогда вы можете поместить это в словарь или итерировать или что-то еще.

0 голосов
/ 07 декабря 2011

Как насчет:

Dictionary<string, int> dictionary = new Dictionary<string, int>();
string delimitedTags = "some tab delimited string";
List<string> tags = delimitedTags.Split(new char[] {'\t'}, StringSplitOptions.None).ToList();
foreach (string tag in tags.Distinct())
{
    dictionary.Add(tag, tags.Where(t => t == tag).Count());
}
0 голосов
/ 07 декабря 2011

Вероятно, проще просто заново добавить значение словаря после того, как вы извлечете счетчик из существующего.

Вот некоторый псевдо-код для обработки логики поиска.

Dictionary<string, int> _dictionary = new Dictionary<string, int>(); 

private void AdjustWordCount(string word)
{

  int count;
  bool success = _dictionary.TryGetValue(word, out count);

  if (success)
  {
    //Remove it 
    _dictionary.Remove(word);
    //Add it back in plus 1
    _dictionary.Add(word, count + 1);
  }
  else  //could not get, add it with a count of 1
  {
    _dictionary.Add(word, 1);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...