简体   繁体   中英

Dictionary<string, int> increase value

I have a Dictionary<string, int> and I am reading some strings from a list... I want to add them in the dictionary, but if the string is already in the dictionary, I want its value to increase by 1.

The code I tried is as below, but there are some strings that are increased with every input.. Is something wrong?

    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);
            }
        }
    }

EDIT: To answer your comments... I am removing the last char of the string because it is always a blank space... My input is like:

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

and i want only the string like "business" or "management & auxiliary services" etc.

You are splitting each string in the input string array and selecting the 2nd string in the string array. Then you are removing the last character of this 2nd string using SubString . Hence all strings that differ only in the last character would be considered the same and incremented. Thats why you might be seeing "some strings that are increased with every input".

EDIT: If the purpose of removing the last char is to remove space, Use String.Trim instead. Another edit is using TryGetValue instead of ContainsKey which performs better to increment your value. Code has been edited below.

Try this:

    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;
    }

No need for a dictionary, can be solved using this Linq query.
(Assuming you want the complete string after \\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()
    };

And if you need it as a dictionary just add:

var dic = q.ToDictionary (x => x.Key, x => x.Count);

您的输入字符串首先拆分 ,然后它的子字符串返回到tagToDic,所以也许n个字符串具有相同的 tagToDic。

Extension method

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");

It's probably easier just to re-add the dictionary value after you retrieve the count from the existing one.

Here's some psuedo code to handle the look up logic.

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);
  }
}

How about:

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());
}

If you have them in a list you could just group them and make your list.

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

Then you can put that in a dictionary or iterate it or something.

Your dictionary code looks like it will function the way you expect.

My best guess is that your string-splitting code is not working correctly.
You'd have to give us some sample inputs to verify this though.

Anyway, your entire block of code could be simplified and rewritten with LINQ as:

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())
    ;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM