【问题标题】:cancelling out possibility of repeat display using ternary operator使用三元运算符消除重复显示的可能性
【发布时间】:2020-04-07 20:49:49
【问题描述】:

我正在使用 React 构建一个抽认卡应用程序来帮助保留编程概念。到目前为止,我已将应用程序设置为在卡片的正面显示带有概念定义/解释的卡片,并在背面显示相应的术语/概念。用户可以通过单击按钮翻转卡片并更改为不同的卡片。问题是目前,onClick 有时会显示之前显示的卡片。我想防止这种情况发生。我尝试使用三元运算符这样做,但不知何故,我的 Javascript 逻辑是错误的,因为我仍然得到重复显示。我该如何解决这个问题?

代码如下:

// data and components
import { conceptArray } from "./data";
import FlashCard from "./components/FlashCard";

function App() {
  const [randomCard, setRandomCard] = useState({});
  const [mode, setMode] = useState(true);

  // this should store the individual concept (individual items in the concept Array) to later be displayed as a card
  const getCard = () => {
    // this changes the card and posits that there can be no repeat display of card that was displayed immediately before
    let newCard = conceptArray[Math.floor(Math.random() * conceptArray.length)];
    newCard !== randomCard ? setRandomCard(newCard) : newCard = conceptArray[Math.floor(Math.random() * conceptArray.length)];
    // this allows for the front of the card(ie. the definition) to be displayed
    setMode(true);
  };

  const flip = () => {
    // this allows for the back of the card (ie. the term itself) to be displayed
    setMode(!mode);
  }

  console.log(randomCard);

  return (
    <div className="App">
      <header className="App-header">
        <FlashCard randomCard={randomCard} mode={mode} />
        <button onClick={getCard}>Get FlashCard</button>
        <button onClick={flip}>Flip</button>
      </header>
    </div>
  );
}

export default App;

【问题讨论】:

  • 如何保留一个存储最后三个随机(数字)的数组并将每个新数组与您拥有的数组进行比较
  • 这听起来比它需要的更复杂。但我愿意考虑这一点。你能建议这个代码吗? @米莎
  • 如何将conceptArray 洗牌进入状态。然后每次选择一张卡片时取出数组中的第一项(用其余的更新状态)。当状态为空时,你重新洗牌概念数组...
  • 这难道不是把卡片整理好@ThomasWikman 吗?我实际上希望卡片顺序是随机的。
  • 把它想象成一副纸牌。你洗牌,拿走最上面的牌。你只需要在重新洗牌之前弄清楚你是否希望选择的牌再次回到牌组中,或者你是否希望牌组是空的。

标签: javascript reactjs onclick conditional-operator


【解决方案1】:

所以我最终接受了将 conceptArray 改组为状态的建议。我使用了 Fisher-Yates(又名 Knuth)Shuffle 来执行此操作,可以在这里找到:How to randomize (shuffle) a JavaScript array?。我还不完全理解它背后的逻辑,但我能够将它应用到我的代码中并让它工作。现在,牌是按随机顺序抽取的,没有立即重复。

正如 Thomas Wikman 简洁地解释的那样,这就像洗牌 conceptArray 中的项目,类似于洗牌的方式。一旦发生这种情况,我使用 onClick 从该数组中获取第一个项目,过滤掉该数组以排除正在获取的概念,然后继续获取另一个。一旦我完成了数组中的最后一个概念,我再次执行洗牌并重新开始。

如果这对其他人有帮助,下面是生成的代码:

// data and components
import { conceptArray } from "./data";
import FlashCard from "./components/FlashCard";
import AddForm from "./components/AddForm";

function App() {
  // Fisher-Yates (aka Knuth) Shuffle
  // don't completely understand it but I got it to work
  const shuffle = array => {
    var currentIndex = array.length, temporaryValue, randomIndex;

    // While there remain elements to shuffle...
    while (0 !== currentIndex) {

      // Pick a remaining element...
      randomIndex = Math.floor(Math.random() * currentIndex);
      currentIndex -= 1;

      // And swap it with the current element.
      temporaryValue = array[currentIndex];
      array[currentIndex] = array[randomIndex];
      array[randomIndex] = temporaryValue;
    }

    return array;
  }

  // puts shuffled array of concepts into state
  const [cardArray, setCardArray] = useState(shuffle(conceptArray));
  const [randomCard, setRandomCard] = useState({});
  const [frontMode, setFrontMode] = useState(true);
  const [formMode, setFormMode] = useState(false);

  // stores the individual concept (individual item in the concept Array) to be displayed as a card
  const getCard = () => {
    // grabs the first item in the shuffled array
    setRandomCard(cardArray[0]);
    // filters array so that item already displayed on card cannot be shown again until array is reshuffled
    setCardArray(cardArray.filter(item => item !== cardArray[0]));
    // when there is only one item left in filtered array, shuffles entire array again
    if (cardArray.length === 1) {
      setCardArray(shuffle(conceptArray));
    }
    // this allows for the front of the card(ie. the definition) to be displayed
    setFrontMode(true);
  };

  const flip = () => {
    // this allows for the back of the card (ie. the term itself) to be displayed
    setFrontMode(!frontMode);
  }

  const renderForm = () => {
    setFormMode(true);
  }

  // console.log(randomCard);
  // console.log(conceptArrayRandomized);
  // console.log(conceptArray);


  return (
    <div className="App">
      {!formMode && <FlashCard randomCard={randomCard} frontMode={frontMode} />}
      {!formMode && <button onClick={getCard}>Get FlashCard</button>}
      {!formMode && <button onClick={flip}>Flip</button>}
      <br />
      {!formMode && <button onClick={renderForm}>Add New</button>}
      {formMode && <AddForm />}
    </div>
  );
}

export default App;

【讨论】:

    【解决方案2】:

    如果您参考 SOF 上的this 问题,可以应用许多解决方案。 请检查此功能,如果您需要随机数组,则可以全局使用它,只需传递数组长度

    const generate_random_number = (_objLength) => {
    
    let random_array_of_integers = [];
    
    while (random_array_of_integers.length < _objLength) {
        let random_integer = Math.floor(Math.random() * _objLength);
        if (!random_array_of_integers.includes(random_integer))
            random_array_of_integers.push(random_integer);
    }
    
    
      return random_array_of_integers;
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-06
      • 2021-04-14
      • 2018-08-12
      • 2015-07-31
      • 2012-02-02
      • 2021-03-31
      • 2021-09-11
      • 2018-10-27
      相关资源
      最近更新 更多