数组自动洗牌 5 次
Shuffle array automatically 5 times
我已经编写了 JavaScript 函数,用于在点击时随机播放一组 div。
// 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 自动 sort/shuffle 5 次,onClick。
(IE = 我不想点击 5 次,随机播放 5 次)。
执行此操作的最佳方法是什么?
(我已经搜索过但没有找到任何可以重复洗牌的元素)。
我考虑过使用异步 await/settimeout,重复 this.state.divs.sort(() => Math.random() - .50)
5 次?
更新:
要添加上下文,这里是一个codesandbox...
https://codesandbox.io/s/distracted-shape-ifsiv
当我点击随机播放按钮时,你可以看到帽子只交换一次位置。不是5次。
我不明白为什么洗牌 5 次比洗牌 5 次更好或有什么不同。不管怎样,你可以像这样用一种天真的方式来做:
// 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
函数,如下所示:
// 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 次和 5 次效果相同,Fisher-Yates 效率更高,但保持你的方式:
shuffle = () => {
let shuffled = [];
for(let i=0; i<5; i++)
shuffled = this.state.divs.sort(() => Math.random() - .50);
this.setState([...shuffled]);
};
如果您决定使用 "Fisher-Yates" 算法,您可以像这样实现它:
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()
的方法有时 returns 相同的结果,而 "Fisher–Yates" 总是重新洗牌。
<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>
<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>
对于你的情况,它就像:
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)
}
这是一种可行的方法,javascript。
hats
对象被洗牌 5 次,第二个转换为 200 毫秒。
当然很简单,对象就是用来扩展的!
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("")
}
div {display: flex; font-size: xx-large }
<button onclick="loop5()">shuffle hats</button>
<div id="out"></div>
我已经编写了 JavaScript 函数,用于在点击时随机播放一组 div。
// 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 自动 sort/shuffle 5 次,onClick。
(IE = 我不想点击 5 次,随机播放 5 次)。
执行此操作的最佳方法是什么?
(我已经搜索过但没有找到任何可以重复洗牌的元素)。
我考虑过使用异步 await/settimeout,重复 this.state.divs.sort(() => Math.random() - .50)
5 次?
更新:
要添加上下文,这里是一个codesandbox... https://codesandbox.io/s/distracted-shape-ifsiv
当我点击随机播放按钮时,你可以看到帽子只交换一次位置。不是5次。
我不明白为什么洗牌 5 次比洗牌 5 次更好或有什么不同。不管怎样,你可以像这样用一种天真的方式来做:
// 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
函数,如下所示:
// 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 次和 5 次效果相同,Fisher-Yates 效率更高,但保持你的方式:
shuffle = () => {
let shuffled = [];
for(let i=0; i<5; i++)
shuffled = this.state.divs.sort(() => Math.random() - .50);
this.setState([...shuffled]);
};
如果您决定使用 "Fisher-Yates" 算法,您可以像这样实现它:
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()
的方法有时 returns 相同的结果,而 "Fisher–Yates" 总是重新洗牌。
<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>
<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>
对于你的情况,它就像:
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)
}
这是一种可行的方法,javascript。
hats
对象被洗牌 5 次,第二个转换为 200 毫秒。
当然很简单,对象就是用来扩展的!
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("")
}
div {display: flex; font-size: xx-large }
<button onclick="loop5()">shuffle hats</button>
<div id="out"></div>