搜尋

首頁  >  問答  >  主體

標題重寫:值選擇與變數賦值問題的故障排除

對於 Hangman 遊戲,我有一些主題(例如:城市和動物)。

當使用者選擇其中一個主題時,結果應該是所選主題的隨機項目之一。例如:倫敦或斑馬線等。

目前我只有所選主題的隨機字母。

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>

P粉596161915P粉596161915267 天前495

全部回覆(2)我來回復

  • P粉691461301

    P粉6914613012024-03-31 09:15:05

    在您現有的程式碼中,topicsEl.value 將是字串「cities」或字串「animals」(因為這些是<select> 框中每個選項的值。)。這些不是您在 JavaScript 中定義的全域變量,它們只是 HTML 中包含的字串。

    然後,在 randomTopic() 中,將該字串作為數組訪問,Javascript 將其解釋為您希望將其視為該字串中的字元數組。這就是為什麼您會從單字中獲得一個隨機字母:"animals"[0] 是字母 a,"animals"[1] 是字母 n,依此類推。

    嘗試要做的是從您命名為「城市」和「動物」的數組變數中選擇一個隨機項目,但您的函數不會嘗試觸及這些變量,它們只作用於DOM 中包含的字串。

    因此,您需要新增一個步驟,從 <select> 中的字串值取得到您嘗試存取的陣列。

    您已將兩個陣列定義為全域變數;理論上,這些可以作為window.citieswindow.animals 進行訪問,因此您可以執行window [topicsEl.value] 這將返回您嘗試訪問的數組....依賴於視窗並不是很好的做法不過,全域變量,所以我鼓勵您將這對單獨的變量切換到一個物件中以便於訪問:

    const topics = {
      cities: ["New York", "London", "Berlin"],
      animals: ["Alligator", "Alpaca", "Zebra"]
    }
    
    const topicsEl = document.querySelector("#topics")
    
    function randomTopic() {
      // find the desired array:
      let topicArr = topics[topicsEl.value]
      // return a random element from that array:
      return topicArr[Math.floor(Math.random() * topicArr.length)]
    }
    
    topicsEl.addEventListener("change", function() {
      console.log(randomTopic());
    })

    回覆
    0
  • P粉696605833

    P粉6966058332024-03-31 00:41:15

    您似乎在根據選擇獲取清單的隨機值時遇到問題。

    目前,您正在選擇 topicsEl.value 的隨機字母,而不是關聯主題清單的隨機元素。

    您需要根據 topicsEl.value 確定要選擇的清單。如果該值可以用作鍵(例如對於字典),則可以動態地實現這一點,但這也可以是靜態完成。

    但是靜態執行會導致重複程式碼,例如在每個新主題清單不斷增長的 if-else-if 階梯中:

    function randomTopic() {
      if (topicsEl.value === "cities") {
        // ... (use citites)
      } else if (topicsEl.value === "animals") {
        // ... (use animals)
      } // Etc. for every new topic
    }
    

    動態地執行此操作可以抽象化清單選擇,從而保持功能簡單。正如之前所建議的,可以使用字典來實現此目的。

    例如,字典的每個屬性都可以是主題列表,然後您的選項值應與其對應屬性的名稱相符:

    const topics = {
      cities: [/*...*/],
      animals: [/*...*/]
    };
    
    const topicsEl = document.querySelector("#topics");
    
    function randomTopic() {
      const list = topics[topicsEl.value];
      // ...
    }
    

    選擇該清單中的隨機項目類似於您目前選擇隨機字母的方式:

    function randomTopic() {
      const list = topics[topicsEl.value];
      return list[Math.floor(Math.random() * list.length)];
    }
    

    就我個人而言,如果索引產生位於單獨的函數中,我發現這種隨機選擇更具可讀性。範例:

    const edibles = ["cheese", "ham", "bread", "banana", "peanuts"];
    console.log(randomEdible());
    
    function randomEdible() {
      return edibles[randomInt(0, edibles.length - 1)];
    }
    
    function randomInt(max = 100, min = 0) {
      if (max < min) {
        [max, min] = [min, max]; // Swap
      }
      
      return Math.floor(Math.random() * (max - min + 1) + min); // +1 to include max
    }

    回覆
    0
  • 取消回覆