首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >自动洗牌5次

自动洗牌5次
EN

Stack Overflow用户
提问于 2019-12-29 17:34:46
回答 3查看 466关注 0票数 3

我编写了JavaScript函数,以洗牌一个divs数组。

代码语言:javascript
运行
复制
  // Function to shuffle 3 divs
  shuffle = () => {
    const shuffled = this.state.divs.sort(() => Math.random() - .50);
    this.setState([...shuffled]);
  };

  // Button as an FYI
  <button onClick={this.shuffle} className="has-text-black">shuffle hats</button>

这是非常好的工作,并随机每次我点击按钮。

但是,我希望div自动排序/洗牌5次,onClick。

(我不想点击5次,洗牌5次)。

做这件事最好的方法是什么?

(我已经搜索过了,但没有发现任何可以对元素进行重复调整的东西)。

我考虑过使用异步等待/设置超时,重复this.state.divs.sort(() => Math.random() - .50) 5次吗?

更新:

要添加上下文,这里有一个代码框..。https://codesandbox.io/s/distracted-shape-ifsiv

当我点击洗牌按钮,你可以看到帽子只交换一次位置。不是5次。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-12-29 18:58:25

下面是使用javascript的一种可行的方法。

hats对象被洗牌5次,有200 get的第二次转换。

当然,它非常简单,对象是要扩展的!

代码语言:javascript
运行
复制
let hats = [
  {content: `<h6>1</h6>`},
  {content: `<h3>2</h3>`},
  {content: `<h1>3</h1>`},
  {content: `<h2>4</h2>`},
  {content: `<h4>5</h4>`}
];
let timer;

function loop5(){
  let i = 0
  clearInterval(timer)
  timer = setInterval(function(){
    shuffle()
    if (i >= 5){
      clearInterval(timer)
    } 
    i++    
  }, 200)
}

function shuffle(){
   hats.sort(() => Math.random() - 0.5)
   out.innerHTML = hats.map(e => e.content).join("")
}
代码语言:javascript
运行
复制
div {display: flex; font-size: xx-large }
代码语言:javascript
运行
复制
<button onclick="loop5()">shuffle hats</button>
<div id="out"></div>

票数 2
EN

Stack Overflow用户

发布于 2019-12-29 17:40:11

我不明白为什么5次洗牌比5次洗牌更好或者有什么不同。不管怎样,你可以用一种天真的方式做这件事:

代码语言:javascript
运行
复制
// Function to shuffle 3 divs
  shuffle = () => {
    const shuffled = this.state.divs.sort(() => Math.random() - .50);
    this.setState([...shuffled]);
  };

  shuffleTimesFive = () => {
     for(var i = 0; i < 5; i++) 
         this.shuffle();
  }

  // Button as an FYI
  <button onClick={this.shuffleTimesFive} className="has-text-black">shuffle hats</button>

或者,更明智的方法是拥有一个接受参数的shuffleNTimes函数,如下所示:

代码语言:javascript
运行
复制
  // Function to shuffle 3 divs
  shuffle = () => {
    const shuffled = this.state.divs.sort(() => Math.random() - .50);
    this.setState([...shuffled]);
  };

  shuffleNTimes = (n) => {
     for(var i = 0; i < n; i++) 
         this.shuffle();
  }

  // Button as an FYI
  <button onClick={this.shuffleNTimes.bind(this, 5)} className="has-text-black">shuffle hats</button>
票数 1
EN

Stack Overflow用户

发布于 2019-12-29 17:44:47

我认为洗牌一次五次也有同样的效果,费舍-耶茨的效率更高,但保持你的方式:

代码语言:javascript
运行
复制
  shuffle = () => {
    let shuffled = [];
    for(let i=0; i<5; i++) 
      shuffled = this.state.divs.sort(() => Math.random() - .50);
    this.setState([...shuffled]);
  };

如果您决定使用"Fisher-Yates“算法,您可以将其实现如下:

代码语言:javascript
运行
复制
const shuffle = () => {
    let array = this.state.divs;
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
    this.setState([...array]);
}

正如我从您的评论中了解到的,您想要做动画,在这种情况下,您不需要一个循环,而是可以使用setInterval()并将其重置--执行五次。我已经编写了关于这两种洗牌方式的演示,因为您可以看到使用sort()的方法有时会返回相同的结果,而“Fisher-Yates”总是被重新洗牌。

代码语言:javascript
运行
复制
<button onclick="shuffle()">Click To Shuffle</button>
<div id="1">div1</div>
<div id="2">div2</div>
<div id="3">div3</div>
<div id="4">div4</div>

<script>
//This one uses Fisher–Yates shuffle algorithm:
  const divs = [...document.querySelectorAll('div')];

  const shuffle = () => {
    let count = 0;
    const intervalId = setInterval( function() {
      for (let i = divs.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [divs[i], divs[j]] = [divs[j], divs[i]];
      }
      divs.forEach( div => document.body.appendChild(div) );
      count++;
      if(count === 5) 
        clearInterval(intervalId);
    } ,1000)
  }

</script>

代码语言:javascript
运行
复制
<button onclick="shuffle()">Click To Shuffle</button>
<div id="1">div1</div>
<div id="2">div2</div>
<div id="3">div3</div>
<div id="4">div4</div>

<script>

  const divs = [...document.querySelectorAll('div')];

  shuffle = () => {
    let shuffled = [];
    let count = 0;
    const intervalId = setInterval( function() {
      shuffled = divs.sort(() => Math.random() - .50);
      shuffled.forEach( div => document.body.appendChild(div) );
      count++;
      if(count === 5) 
        clearInterval(intervalId);
    }, 1000 )
  };

</script>

就你的情况而言,就像:

代码语言:javascript
运行
复制
  let divs = this.state.divs;

  const shuffle = () => {
    let count = 0;
    const intervalId = setInterval( function() {
      for (let i = divs.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [divs[i], divs[j]] = [divs[j], divs[i]];
      }
      this.setState([...divs]);
      count++;
      if(count === 5) 
        clearInterval(intervalId);
    } ,1000)
  }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59521734

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档