-2

I am trying to figure how to work with a list of KeyValuePairs in C#. I would use dictionaries but they do not allow for duplicate values.

Also the lookup which also i cannot figure out how to write the syntax.

I have seen other solutions but i am really confused on how to work with

Of course the only example i could find is with for loop, i would like to have it a little cleaner.

List<KeyValuePair<char, int>> data = new List<KeyValuePair<char, int>>();

I would like for example to do some checking before i add an element. For example: I have an array of characters, which i want to check before adding it to the my list. Can anyone tell me how to check.

char[] inputArray = input.ToCharArray();
for(int i = 0; i < inputArray.Length ; i++)
{
    if(!data.Values.Contains(inputArray[i]))
    {
        data.Add(new KeyValuePair<char,int>(inputArray[i], 1));
    }
}

The above code does not work. Could someone please help a bit with the syntax.

I did not found any concrete examples around the web. Any help is appreciated.

panoskarajohn
  • 1,846
  • 1
  • 21
  • 37
  • 2
    I have no idea what it is you are trying to do. The whole point of a dictionary is to store unique keys... so no, it does not allow duplicates and would be very bad if it did. – theMayer Apr 30 '18 at 18:17
  • 3
    Ok, so you say you don't want duplicate keys, but your loop looks like it is checking for duplicate entries and not adding them, so I'm not sure why you can't use a Dictionary? You are also checking the array against the keys but adding `1` to the values with the array as the key, which also doesn't make a lot of sense... – Ron Beyer Apr 30 '18 at 18:23
  • 1
    Your problem is that "data", which is a list, doesn't have a "Values" method. Note Cocowalla's syntax in his answer. The Any() method is effectively looping through your list of kvp and comparing each key. Also, if your logic is attempting to prevent duplicate keys, you should just use Dictionary, it is much easier to work with. – user7396598 Apr 30 '18 at 18:29

2 Answers2

1

I have to say, your question is rather confusing. I think you're trying to add values to a list of KeyValuePair, if the key doesn't already exist? That doesn't seem to fit with what you say about not using a Dictionary, but here you go anyway:

List<KeyValuePair<char, int>> data = new List<KeyValuePair<char, int>>();

char[] inputArray = "my string".ToCharArray();
foreach (var t in inputArray)
{
    if (!data.Any(x => x.Key == t))
    {
        data.Add(new KeyValuePair<char, int>(t, 1));
    }
}

If you just want to get the unique values from inputArray, you could also just do:

var myVals = inputArray.Distinct();

And finally, if you want to get the count of each distinct character in a string, you can use:

var counts = inputArray.GroupBy(x => x)
    .Select(group => new
    {
        Character = group.Key,
        Count = group.Count()
    });
Cocowalla
  • 13,822
  • 6
  • 66
  • 112
  • Thank you for your answer that is excactly what i wanted. I wanted to have a cleaner looking syntax and avoiding the extra for loop. You are right on point, Thank you for your answer. – panoskarajohn Apr 30 '18 at 18:33
  • @panoskarajohn why aren't you using a Dictionary if you are never entering duplicate values? – maccettura Apr 30 '18 at 18:36
  • I saw the limit to the Dictionary and cared to ask, if i wanted done this way i would not ask the question. Seems everybody is upset i asked. Sorry for wasting your time. – panoskarajohn Apr 30 '18 at 18:38
  • 1
    @panoskarajohn no one is upset, we are all here to help. Based on what you are asking a Dictionary seems to be a better fit. [XY Problems](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) are extremely common here and we ask these questions to try and help. Your question indicates that `Dictionaries cannot contain duplicate values" which is false, they cannot contain duplicate "keys". Since this answer and your codes logic _never_ allow a duplicate key to be added it seems like a Dictionary is the obvious solution – maccettura Apr 30 '18 at 18:39
  • @panoskarajohn `H` and `E` do not have the same key, they have the same _value_ (i.e 1). The keys should be the chars (as it is in your example). But if you want to find the character that appears the most in a string you can do it much simpler with LINQ. – maccettura Apr 30 '18 at 18:47
  • 1
    @panoskarajohn I really think Dictionary is what you want to use if you are against using Linq. Dictionary has much quicker duplicate checking functionality then iterating over the entire collection. – maccettura Apr 30 '18 at 19:00
  • @maccettura you are right bad example. I cannot think of a use case now. Thank you for your time. – panoskarajohn Apr 30 '18 at 19:06
0

Based on your comments it really sounds like you want a Dictionary here.

Consider your logic, you already check for duplicates before adding to a list right? That means your list will never have duplicates. Dictionary's prevent you from having duplicate keys, not duplicate values. So your logic could easily become:

var dictionary = new Dictionary<char, int>();
foreach(char c in input)
{
    //faster than Any()
    if(!dictionary.ContainsKey(c))
    {
        dictionary.Add(c, 1);
    }
}
maccettura
  • 10,514
  • 3
  • 28
  • 35