从1000个元素的数组中获得50个随机唯一元素的最简单方法是什么?来自1000个元素阵列的50个随机独特元素?
text = new Array();
for(i=0;i<1000;i++){ text[i]=i; } //array populated
// now I need to get 50 random unique elements from this array.
从1000个元素的数组中获得50个随机唯一元素的最简单方法是什么?来自1000个元素阵列的50个随机独特元素?
text = new Array();
for(i=0;i<1000;i++){ text[i]=i; } //array populated
// now I need to get 50 random unique elements from this array.
设置一个变量等于Math.random(),每次循环运行时调用该变量并将该变量作为索引。按照数组大小调整随机调用,在这种情况下为1000.这会给你50个随机元素。
好算法this topic解释(在C,但你可以很容易地在JS做相同)
明显的(对我)的办法就是重新洗牌的阵列,然后采取前五元素。 This question有一个很好的方式来洗牌一个数组,然后你可以在第一个五十个元素中使用slice
。这保证了元素将是唯一的。
因此,使用该功能有:
fisherYates(text);
text = text.slice(0, 50);
好主意!但是,只有1000个元素是唯一的,它才会起作用。 – VisioN
@VisioN在这种情况下,确保'text'中的元素是唯一的。有很多功能可以用来做这个,比如[this one](http://www.jslab.dk/library/Array.unique)。 – lonesomeday
VisioN是正确的,洗牌1000个len阵列也很昂贵 – ajax333221
查找到Fisher-Yates algorithm,我认为这会为你工作。
如果你的意思是唯一值:
var old_arr = [0,1,2,3,4,5,6,7,8,9], new_array = [];
for (var i = 0; i < 5; i++) {
var rand_elem = old_arr[Math.floor(Math.random() * old_arr.length)];
if (arrIndex(old_arr[rand_elem], new_array) == -1) {
new_array.push(rand_elem);
} else {
i--;
}
}
function arrIndex(to_find, arr) {//own function for IE support
if (Array.prototype.indexOf) {
return arr.indexOf(to_find);
}
for (var i = 0, len = arr.length; i < len; i++) {
if (i in arr && arr[i] === to_find) {
return i;
}
}
return -1;
}
如果你的意思是独特的指数法:
var arr = [];
while(arr.length < 51){
var ind = Math.floor(Math.random()*1000);
if(!(ind in arr))
arr.push(ind)
}
您将有50个随机识别号数组ARR,你可以使用作为指数
编辑:
正如@ ajax333221提到,以前的代码没有得到从数组的独特元素,在情况下,它包含重复。因此,这是修复:
var result_arr = [];
while(result_arr.length < 51){
var ind = Math.floor(Math.random()*1000);
if(text[ind] && !(text[ind] in result_arr))
result_arr.push(text[ind]);
}
是“文”填充1000个值
-1 a)不会正确生成唯一编号b)即使您修复它,如果1k数组包含重复项,那么唯一编号也是无用的 – ajax333221
是的,您错了,我误解了这个问题,索引号码。你为什么说它不会正确生成唯一的数字? – davids
@d因为'if(!(ind in arr))'不是正确的检查,它会检查索引是否包含在数组中(而不是数值)。所以如果你在第一个循环中添加23,23可能会复制下一个循环。你可能想用indexOf代替 – ajax333221
这里假设你的意思是随机指标,而不是指标具有唯一值的数组。
一种方法是在阵列复制剪掉你使用的:
function getRandomIndexes(arr, cnt){
var randomArr = [],
arrCopy = arr.slice(),
i,
randomNum ;
for (i=0;i<arrCopy.length;i++) {
randomNum = Math.floor(arrCopy.length * Math.random());
randomArr = randomArr.concat( arrCopy.splice(randomNum ,1));
}
return randomArr;
}
var myNums = [], i, randSet;
for (i=0;i<10;i++){
myNums.push(i);
}
randSet = getRandomIndexes(myNums, 5);
另一种方法是跟踪使用指标和继续找,直到你找到一个你没有使用。我发现while循环是可怕的,如果随机索引需要接近数组长度,我个人不会使用这个解决方案。
function getRandomIndexes(arr, cnt){
var randomArr = [],
usedNums = {},
x;
while (randomArr.length<cnt) {
while (usedNums[x]===true || x===undefined) {
x = Math.floor(Math.random() * arr.length);
}
usedNums[x] = true;
randomArr.push(arr[x]);
}
return randomArr;
}
var myNums = [], i, randSet;
for (i=0;i<10;i++){
myNums.push(i);
}
randSet = getRandomIndexes(myNums, 5);
有趣,第一次看到'arr.slice()'(我总是看到'arr.slice(0)'),但我想它也可以工作 – ajax333221
50个独特元素? – JoshNaro
是的,独特的元素。 – xRobot
你是什么意思的独特元素?你是指索引中的唯一索引或唯一值? – epascarello