我尝试在数组中复制偶数,并在同一个for循环中随机化新复制的元素:
var arr=[0,1,2,3,4,5,6,7,8];
var arr2=[];
for(var i=0;i<arr.length;i++){
if(arr[i]%2==0){
arr2.splice(Math.random()*arr2.length,0,arr[i]);
}
}
document.write(arr2);
概念很简单:将新复制的元素插入新数组的随机位置,但serval输出表明它不正确:
2,6,4,8,0
4,8,6,2,0
6,2,8,4,0
最后总是0。代码有什么问题?或者我的观念错了吗?
答案 0 :(得分:1)
这是一个scopedShuffle函数:
function scopedShuffle(a){
var n = a.slice(), l = n.length;
n.sort(function(b, c){
return 0.5 - Math.floor(Math.random()*(l+1))/l;
});
return n;
}
van resultArray = scopedShuffle(yourArrayHere);
这里的关键是使用n
var n = a.slice()
的范围,这样就不会改变原始数组。
我会使用Constuctor:
function ShuffleMaster(inputArray){
var a = inputArray;
if(!(a instanceof Array)){
throw new Error('inputArray must be an Array');
}
this.getInputArray = function(){
return a;
}
this.setInputArray = function(inputArray){
if(!(inputArray instanceof Array)){
throw new Error('inputArray must be an Array');
}
a = inputArray;
return this; // allows for daisy-chaining
}
this.shuffle = function(){
var n = a.slice(), l = n.length;
n.sort(function(b, c){
return 0.5 - Math.floor(Math.random()*(l+1))/l;
});
return n;
}
}
var myArray = [0, 7, 21, 26, 78, 756];
var sM = new ShuffleMaster(myArray);
console.log(sM.shuffle()); console.log(sM.shuffle());
console.log(sM.setInputArray([4, 5, 85, 46, 11]).shuffle());
console.log(sM.getInputArray());
&#13;
这里是一个简单的闭包样式,其中自执行函数对新数组进行范围限定,因此可以在下次调用时访问它而不传递原始参数...几乎是静态的。
var scopedShuffle = (function(){
var a;
return function(inputArray){
if(inputArray){
a = inputArray.slice();
}
var n = a.slice(), l = n.length;
n.sort(function(b, c){
return 0.5 - Math.floor(Math.random()*(l+1))/l;
});
return n;
}
})();
console.log(scopedShuffle(['a', 2, 4, 'g', 'apes']));
console.log(scopedShuffle()); console.log(scopedShuffle());
console.log(scopedShuffle(['learning', 'you', 'now', 'are', 'monkeys', 42, 'life', 'itself', 'the Universe']));
console.log(scopedShuffle()); console.log(scopedShuffle());
&#13;
答案 1 :(得分:0)
Math.random()
会返回介于0和0之间的数字独占。这意味着Math.random()*arr2.length
总是少而不是arr2.length
,因此任何元素都不会被拼接到数组的末尾 - 除了在循环的第一次迭代时数组为空,因此0
最终成为其第一个也是唯一的元素。但是后续迭代会在除结尾之外的任何位置插入随机位置,因此始终将0
推向右侧。
您可以将Math.random()*arr2.length
更改为Math.random() * (arr2.length + 1)
。
另请注意.splice()
似乎并不关心您是否传递了一个不是整数的数字,但为了整洁,我更倾向于使用Math.floor(Math.random() * (arr2.length + 1))
演示:
function makeArray() {
var arr=[0,1,2,3,4,5,6,7,8];
var arr2=[];
for(var i=0;i<arr.length;i++){
if(arr[i]%2==0){
arr2.splice(Math.floor(Math.random()*(arr2.length+1)), 0, arr[i]);
}
}
return arr2;
}
console.log(JSON.stringify(makeArray()));
console.log(JSON.stringify(makeArray()));
console.log(JSON.stringify(makeArray()));
console.log(JSON.stringify(makeArray()));
console.log(JSON.stringify(makeArray()));
console.log(JSON.stringify(makeArray()));
console.log(JSON.stringify(makeArray()));
&#13;
答案 2 :(得分:0)
简单解决方案:长链方法(slice
,filter
,sort
)。
首先使用.slice(0)
进行克隆,然后.filter()
过滤掉奇数,最后使用.sort
和Math.random()
进行随机播放。
var arr2 = arr.filter(function(a) {
return (a % 2) === 1; // Return true if a is even
}).sort(function() {
return 0.5 - Math.random();
};
参见示例:
function shuffleIt() {
var arr = document.getElementById('numberlist').value.split(' ');
var arr2 = arr.filter(function(a){return a%2 === 0}).sort(function(){return 0.5-Math.random()});
document.getElementById('output').innerHTML = arr2.join(',');
}
&#13;
Type a list of numbers (separate with spaces)
<input type="text" id="numberlist" value="1 2 3 4 5 6 7 8"/>
<button onclick="shuffleIt()">Shuffle evens (click multiple times to get different results) </button>
<br/>
<b>Output:</b>
<div id="output"></div>
&#13;
详细说明:
.filter()
调用在数组的每个元素上传递给它的回调函数。如果函数返回true,则保留元素;如果为false,则删除它。 a % 2 === 0
是检查a是否为偶数的条件,因此这将删除所有非偶数。此方法不会改变数组,而是返回一个新数组。
filter()方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
.sort
对数组进行排序。它一次比较两个项目,使用从ma函数返回的数字的符号决定哪一个项目在另一个项目之前:如果compareFunction(a,b)小于0,则将a排序为低于b的索引,即a先到先得。 如果compareFunction(a,b)[传入的回调函数]返回0,则保持a和b相对于彼此保持不变,但是对于所有不同的元素进行排序。注意:ECMAscript标准不保证这种行为,因此并非所有浏览器(例如可追溯到至少2003年的Mozilla版本)都尊重这一点。 如果compareFunction(a,b)大于0,则将b排序为低于a的索引。 当给定一对特定元素a和b作为其两个参数时,compareFunction(a,b)必须始终返回相同的值。如果返回不一致的结果,则排序顺序未定义。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
如您所见,返回数字的符号决定了首先出现的数组项。 (0.5-Math.random())
随机返回正数或负数(技术上可能为0,但非常不可能),因此随机排序数组。 注意:此函数会改变数组,但我们使用.filter()
创建了一个新数组,因此原始数据仍未改动。