For the Hangman game, I have some themes (for example: cities and animals).
When the user selects one of the themes, the result should be one of the random items from the selected theme. For example: London or zebra crossing, etc.
Currently I only have random letters for the chosen theme.
const cities = ["New York", "London", "Berlin"] const animals = ["Alligator", "Alpaca", "Zebra"] const topicsEl = document.querySelector("#topics") function randomTopic(){ return topicsEl.value[Math.floor(Math.random()*topicsEl.value.length)] } topicsEl.addEventListener("change", function(){ console.log(randomTopic()); })
<div class="select"> <label for="topics">Choose a topic:</label> <select id="topics"> <option value=cities>Cities</option> <option value=animals>Animals</option> </select> </div>
In your existing code,
topicsEl.value
would be the string "cities" or the string "animals" (because these are the<select>
value of an option.). These are not global variables that you define in JavaScript, they are just strings contained within the HTML.Then, in
randomTopic()
, access the string as an array and Javascript interprets it as an array of characters within the string that you want to treat it as. That's why you get a random letter from the word:"animals"[0]
is the letter a,"animals"[1]
is the letter n, and so on.What youtry do is select a random item from the array variables you named "city" and "animal", but your function doesn't try to touch those variables, they just act on String contained in the DOM.
So you need to add a step to get from the string value in
<select>
to the array you are trying to access.You have defined both arrays as global variables; theoretically, these can be accessed as
window.cities
orwindow.animals
, so you can dowindow [topicsEl.value]
This will return the array you are trying to access....it's not very good practice to rely on window global variables though, so I encourage you to switch the pair of separate variables into one object so Visited:You seem to be having trouble getting a random value for a list based on a selection.
Currently, you are selecting a random
letter
of topicsEl.value, rather than a random element of the associated topics list.You need to determine which list to select based on
topicsEl.value
. This can be achieved dynamically if the value can be used as a key (e.g. for a dictionary), but this can also be done statically.But static execution results in duplicate code, such as in a growing if-else-if ladder with each new topic list:
Doing this dynamically abstracts away list selection, keeping functionality simple. As suggested before, you can use a dictionary for this purpose.
For example, each attribute of the dictionary could be a list of topics, and then your option values should match the names of their corresponding attributes:
Selecting a random item in this list is similar to how you currently select random letters:
Personally, I find this random selection more readable if the index generation is in a separate function. Example: