Hello I am hoping for some help accessing a dictionary contents. I have never used dictionaries before and having an issue figuring out what I am wanting to do. I have a <string, string> dictionary which is a language conversion, The key is a dutch word and the value is the english equivalent. But I was wanting to access the contents of the dictionary randomly. I was hoping to be able to something along the lines of generating a random number and then using that random number to access the key-values. However I think a dictionary might be stored as a binary tree so I do not think this would be possible. Is there anyway I could access the dictionary contents in this manner, so it would be random?
Or does anyone else possibly know of a better way I could store this data and access it randomly
I thought a dictionary would be better for the key value pair, since i want to have a dutch word stored as the key and then the English equivalent stored along with it. I have only really started to get more into data structures and thats with c++ so I am not yet familiar with them all and what they are best for.
I will take a look at the list though, and see if i can solve my problem with that.
I’m not an experienced C# programmer, but i think that a bit of a backwards (but a simpler) solution would be using a List.
Let’s say you’ve made a List.
List<Words> wordList = new List<Words>();
You could possibly just have your words as subentries (?)(unfortunately don’t know the actual name for those) in that list under the same index.
and access them semi-randomly with a for loop, where your index variable (in the square brackets here it’s 1) would be randomly selected at a certain range. Simply replace it with whatever variable you’re going to use for that matter.
If you want to, you could also pick both English and Dutch entries separately by creating separate methods for the respective languages.
You cannot really change keys in the dictionaries, because keys are more like a personal ID for the value that it represents. On the other hand the index variable in the List is just that, an index and Lists are more flexible by design. Dictionaries don’t have an order to them and Lists do, meaning that you can use it to your advantage to randomly access random values.
Dictionaries are not directly meant to be indexed by an integer index. However you could fake it by using an int as key and a struct or class (as gjaccieczoto suggests) to store both strings as value. Usually when you use the dutch word as key you are expected to “query” for it.
A List or array could be indexed directly by a random integer value within it’s bounds. But a foreach could be used to iterate over a dictionary with dutch words as key. You just iterate and let a variable increase by one for each entry. When you have reached the random value you have found the element at that “position”. But this is slow. And keep in mind that order of elements will change when you add key/value pairs. Whereas list elements will remain on their position when adding. They will only shift when inserting (or deleting). So when you somehow depend on the order of elements (meaning to retrieve the same key/value pair for a given index) you should consider your options more carefully. For example when more words are added over development or user translation.
But this could also be faked by removing a certain key value pair and add it with another key again.
And yet you try to help. Thumbs up.
So to give better advise you should tell us more about the usecase, how many entries we are talking about, does it change or is it fixed, do you also need to query for dutch words or only by random index, how often does this need to happen per frame, can elements be taken multiple times or only once and so on. You see there need to be many questions answered for such a “simple” choice as a data structure.
I am thinking of making something along the lines of a shop/resturant etc and the player will be given text that has a certain amount of dutch words in it, for example a sentence could be "Hello, Can I please have ‘dutch food name’ and ‘dutch food name’ and the player would need to click the items in game that corresponds to whatever the dutch words are, or if they click the dutch word the english word would display to them.
I am unsure about how many entries I would be including, maybe 30 . And I was planning on just having it fixed. It wouldnt need to be every frame, it would depend on how quick the player gets it correct.
I have so far used gjaccieczo solution, and so far I think it seems to be working fine (so thank you for that gjaccieczo), its obviously not set up fully yet, so unsure if I will develop issues further into it.
This is the code I have so far, if anyone thinks there could be a better method to what I have so far. Just now I just have it set to a button press, but eventually it will be changed to every time a customer arrives in the game. I just need to figure out some more stuff on that.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Language : MonoBehaviour
{
[SerializeField] List<languageConverstions> languageConvert = new List<languageConverstions>();
public string textValue;
public Text textElement;
// Start is called before the first frame update
void Start()
{
languageConvert.Add(new languageConverstions("tomaat", "tomato"));
languageConvert.Add(new languageConverstions("kaas", "cheese"));
languageConvert.Add(new languageConverstions("sla", "lettuce"));
textElement.text = textValue;
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.E))
{
int randomNum = Random.Range(0, 3);
textElement.text = "Hello I would like " + languageConvert[randomNum].dutchWord.ToString();
if(Input.GetMouseButtonDown(0)) // on dutch word
{
// Show corresponding english word
}
}
}
}
public class languageConverstions
{
public string dutchWord;
public string englishWord;
public languageConverstions(string dutch, string english)
{
dutchWord = dutch;
englishWord = english;
}
}
Do you want “repetition” so a word can be displayed multiple times? Now in your example if you would pick two words the same word could be applied if the random number generator prdoces the same number twice (not that unlikely for 3 entries). If you want to prevent this, you could just use a list, shuffle it randomly (look up fisher-yates shuffle) so its order is randomized, and then just iterate it from 0 - number of entries.
Some remarks to your code if you don’t mind:
languageConverstions should that be LanguageConversions ? Note in C# class-/typenames should be Pascal case.
int randomNum = Random.Range(0, 3); this will break as soon as you add or remove elements. Just use the list size:
int randomNum = Random.Range(0, languageConvert.Count);
I do want to be able to select the same word over different ‘customers’ for instance 3 customers could ask for tomato, but I do not want a single customer to use duplicated words, as in asking for tomato and tomato. I hadnt thought of this though, so thank you for pointing this out.
I have seen tutorials saying to use the naming convention you say, I just cant get out of the habit of using lower camel case, I think it is called. And thank you for the tip to use the list size in Random.Range, did not realise that was a possibility, and it will be a lot more helpful with more contents in the list.
Briefly, all lists, in the regular human sense, are pretty much the same. The differences are in efficiency and ease-of-use. As you’ve seen, a Dictionary (called a Map in C++) can always be rewritten as a list of pairs. A C# List (Vector, in C++) is just an array with code to resize it in a clever way. A linked-list is different and faster when you want to insert or delete from the middle, but it’s still just a list. Red-Black binary trees are great, but are only very fast lists. Likewise the various B-trees (with the rules for when and how to split a node) – they’re just fast and efficient for disk sizes (I think).
In short, you can do anything with a simple list. Worst case you need to write a function with a loop instead of a simple built-in (such as W[“cow”] = “Le Cow”). Then the usual speed rules apply – if there’s a speed problem, and the list is causing it, switch to a faster data-structure.[/QUOTE]