[英]Find all occurrences (letters) in array (word)
我想在React.js中創建一個子手游戲,使用此代碼,當用戶單擊字母時,它將在單詞中搜索字母並顯示她。 當單詞只包含一個相同的字母時,它可以正常工作。 我希望這段代碼可以使用帶有2個“ M”的單詞“ PROGRAMMING”。
handleChooseLetter = (index) => {
const usedWord = [...this.state.usedWord];
const chosenLetter = this.state.letters[index].letter;
var letterPosition = usedWord.indexOf(chosenLetter);
if (letterPosition >= 0) {
hiddenWord.splice(letterPosition, 1, chosenLetter);
this.setState({hiddenWord: hiddenWord});
}
}
我已經嘗試了while循環,但在我的情況下不起作用:
var indices = [];
while(letterPosition >= 0) {
const hiddenWord = [...this.state.hiddenWord];
indices.push(letterPosition);
letterPosition = usedWord.indexOf(chosenLetter, letterPosition + 1);
hiddenWord.splice(letterPosition, 1, chosenLetter);
this.setState({hiddenWord: hiddenWord});
}
對我來說,結果是找到字母並始終顯示單詞的最后一個字母。
我認為我的問題是使用拼接方法拼接了錯誤的字母
這里我的chooseWord函數:
state = {
wordList: [
{ id: 1, word: 'PROGRAMMING'},
],
usedWord: [],
hiddenWord: [],
}
chooseWord() {
const wordList = [...this.state.wordList];
const listLength = wordList.length;
const randomWord = this.state.wordList[Math.floor(Math.random() * listLength)].word;
const splittedWord = randomWord.split("");
const arr = new Array(randomWord.length + 1).join("_").split("");
this.setState({
usedWord: splittedWord,
hiddenWord: arr
});
}
最簡單的方法是replace
,而不使用數組:
const usedWord = "programming"; const chosenLetter = "m"; const hiddenWord = usedWord.replace(new RegExp("[^" + chosenLetter + "]", "g"), "_"); console.log(hiddenWord);
隨着用戶添加更多字母,您可以將它們添加到字符類中:
const usedWord = "programming"; const chosenLetters = "mp"; const hiddenWord = usedWord.replace(new RegExp("[^" + chosenLetters + "]", "g"), "_"); console.log(hiddenWord);
React示例:
class Hangman extends React.Component { constructor(...args) { super(...args); this.state = { availableLetters: "abcdefghijklmnopqrstuvwxyz", chosenLetters: "", word: this.props.word }; this.chooseLetter = this.chooseLetter.bind(this); } chooseLetter({target: {tagName, type, value}}) { if (tagName === "INPUT" && type === "button") { this.setState(prevState => ({chosenLetters: prevState.chosenLetters + value})); } } render() { const {word, chosenLetters} = this.state; const hiddenWord = word.replace(new RegExp("[^" + chosenLetters + "]", "g"), "_"); return <div> <div>Word: <span className="hiddenWord">{hiddenWord}</span></div> <div onClick={this.chooseLetter} style={{marginTop: "8px"}}> {[...this.state.availableLetters].map( letter => <input type="button" value={letter} disabled={chosenLetters.includes(letter)} /> )} </div> </div>; } } ReactDOM.render( <Hangman word="programming" />, document.getElementById("root") );
.hiddenWord { font-family: monospace; letter-spacing: 1em; font-size: 18px; }
<div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
對於單個英文字母,您不必擔心使用new RegExp(chosenLetter, "g")
因為沒有英文字母在正則表達式中具有特殊含義。 如果確實有特殊含義的字符( .
, $
等),則在將字符傳遞給RegExp
構造函數之前會對其進行轉義。 請參閱此問題的答案以了解解決方法。
我添加了字母輸入<input onChange={this.handleChooseLetter} value={letter} />
並更改了handleChooseLetter函數,以便在找到至少1個字母時對使用的單詞的字母進行迭代(因為您的usedWord.indexOf(chosenLetter)
總是只返回1個索引),所以我決定遍歷整個單詞並檢查所選字母,如果該索引上的字母存在,我只是將該字母插入到同一索引中的隱藏單詞中-因為隱藏單詞和使用過的單詞的長度相同:
class App extends React.Component { constructor(props) { super(props); this.state = { hiddenWord: "___________", usedWord: "PROGRAMMING", letter: "" }; } handleChooseLetter = e => { const usedWord = [...this.state.usedWord]; const chosenLetter = e.target.value.toLocaleUpperCase(); let letterPosition = usedWord.indexOf(chosenLetter); if (letterPosition > -1) { this.setState(prevState => { const hiddenWord = [...prevState.hiddenWord]; for (let i = 0; i < usedWord.length; i++) { if (usedWord[i] === chosenLetter) { hiddenWord[i] = chosenLetter; } } return { hiddenWord, letter: "" }; }); return; } this.setState({ letter: "" }); }; render() { const { hiddenWord, letter } = this.state; return ( <div className="App"> {[...hiddenWord].map((letter, index) => ( <span key={index}>{letter} </span> ))} <input onChange={this.handleChooseLetter} value={letter} /> </div> ); } } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.1/umd/react-dom.production.min.js"></script> <div id="root"></div>
啊哈! 我上課不得不做一次類似的項目。 繼承人的github倉庫供您參考: https : //github.com/LordKriegan/WraithFood
本質上,我所做的就是創建了一個包含多個字符串和幾個函數的對象。 游戲加載后,它將從我的列表中選擇一個隨機單詞並設置2個字符串。 一個是完整的單詞(讓我們將此屬性稱為fullWord),另一個基本上是一個長度相同的字符串,所有字母都轉換為下划線(我們將其稱為一個guessedWord,也請參閱game.js文件中的setWord())。
但是您有興趣檢查字母! 那很容易。 Javascript字符串具有一個稱為.includes()的內置方法,該方法將字符串作為參數。 由於我已將單詞保存在對象中,因此我只需在該單詞上運行一個.includes()並添加要檢查的字母,然后它是否通過了我的所有驗證(字母已經猜出,單詞中是否存在,等等),我使用另一個名為.charAt(i)的String方法在guessedWord上運行了一個for循環。 此方法僅返回其調用的字符串中位置i處的字符。 由於我必須在對象中輸入字符串,我知道它的長度是相同的,因此可以在fullWord上執行for循環,檢查位置i處的每個字母,然后使用.substr()重置guessedWord屬性。 此方法根據傳遞的參數返回部分字符串。 基本上,我將guessword設置為++。 這是游戲對象中的checkLet()函數。
我建議閱讀https://www.w3schools.com/js/js_string_methods.asp上的字符串方法
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.