87

I am trying to make a method that returns a name of a card from my Dictionary randomly.

My Dictionary: First defined name of the card which is string and second is the value of that card, which is int.

public static Dictionary<string, int> _dict = new Dictionary<string, int>()
    {
        {"7", 7 },
        {"8", 8 },
        {"9", 9 },
        {"10", 10 },
        {"J", 1 },
        {"Q", 1 },
        {"K", 2 },
        {"A", 11 }
    };

Method: random is a randomly generated int.

    public string getCard(int random)
    {
        return Karta._dict(random);
    }

So the problem is:

Cannot convert from 'int' to 'string'

Anybody helps me how should I do it right to get the name?

Hadi
  • 36,233
  • 13
  • 65
  • 124
Jakub Staněk
  • 1,023
  • 1
  • 10
  • 11
  • 1
    Wouldn't it make more sense to make the random value the key? Or, for a well defined set like this, use an array? – FreeText Oct 31 '19 at 16:30

5 Answers5

123

If you need to extract an element key based on an index, this function can be used:

public string getCard(int random)
{
    return Karta._dict.ElementAt(random).Key;
}

If you need to extract the Key where the element value is equal to the integer generated randomly, you can use the following function:

public string getCard(int random)
{
    return Karta._dict.FirstOrDefault(x => x.Value == random).Key;
}

Make sure that you added reference to System.Linq in your class.

using System.Linq;

Side Note: The first element of the dictionary is The Key and the second is the Value

Hadi
  • 36,233
  • 13
  • 65
  • 124
  • 1
    Even with infinite iterations I don't think you would get full coverage when there's duplicate values, which he showed in his example. It probably always gives the "first" one (even though order isn't guaranteed.. just a thought though). – Quantic Nov 03 '16 at 22:41
  • 2
    Thank you! Thats exactly what i was looking for! I tried ElementAt too, but i forgot use the .Key – Jakub Staněk Nov 03 '16 at 22:50
61

You can take keys or values per index:

int value = _dict.Values.ElementAt(5);//ElementAt value should be <= _dict.Count - 1
string key = _dict.Keys.ElementAt(5);//ElementAt value should be  < =_dict.Count - 1
mybirthname
  • 17,949
  • 3
  • 31
  • 55
  • 7
    Just be sure to add using System.Linq; to your program because this is a Linq extension method. – Anton Voronin Aug 07 '17 at 20:44
  • 18
    PERFORMANCE caution: Dictionary does *not* have a quick way to access nth "element" via ElementAt. It does a linear enumeration of the entries, until it reaches the desired element. So each call to ElementAt takes time that increases with the size of the dictionary; performance is O(n). If many calls are needed, and you are not adding new entries to dictionary, then build a *list* of *keys*. Then you can get a random key in O(1) time from that list. – ToolmakerSteve Apr 17 '18 at 16:28
18

you can easily access elements by index , by use System.Linq

Here is the sample

First add using in your class file

using System.Linq;

Then

yourDictionaryData.ElementAt(i).Key
yourDictionaryData.ElementAt(i).Value

Hope this helps.

Noorul
  • 873
  • 2
  • 9
  • 26
3

Your key is a string and your value is an int. Your code won't work because it cannot look up the random int you pass. Also, please provide full code

Deepika Dixit
  • 131
  • 1
  • 7
2

Is it useful to look beyond the exact question asked to alternatives that might better suit the need? Create your own class or struct, then make an array of those to operate on instead of being stuck with the operation of the KeyValuePair collection behavior of the Dictionary type.

Using a struct instead of a class will allow equality comparison of two different cards without implementing your own comparison code.

public struct Card
{
  public string Name;
  public int Value;

}

private int random()
{
  // Whatever
  return 1;
}

private static Card[] Cards = new Card[]
{
    new Card() { Name = "7", Value = 7 },
    new Card() { Name = "8", Value = 8 },
    new Card() { Name = "9", Value = 9 },
    new Card() { Name = "10", Value = 10 },
    new Card() { Name = "J", Value = 1 },
    new Card() { Name = "Q", Value = 1 },
    new Card() { Name = "K", Value = 1 },
    new Card() { Name = "A", Value = 1 }
};

private void CardDemo()
{
  int value, maxVal;
  string name;
  Card card, card2;
  List<Card> lowCards;

  value = Cards[random()].Value;
  name = Cards[random()].Name;
  card = Cards[random()];
  card2 = Cards[1];
  // card.Equals(card2) returns true
  lowCards = Cards.Where(x => x.Value == 1).ToList();
  maxVal = Cards.Max(x => x.Value);

}
B H
  • 1,730
  • 18
  • 24