Javascript-如何按顺序从数组中选取随机元素?

Javascript-如何按顺序从数组中选取随机元素?,javascript,jquery,arrays,random,Javascript,Jquery,Arrays,Random,我有一个数组 var numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"]; 并尝试从中获取随机项,因此: console.log(_.sample(numbers, 5)); 这将以随机顺序从数组中获得5个随机数(字符串),如: "17", "2", "3", "18", "10" 如何获得排序列表或随机项,如 "2", "

我有一个数组

var numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"];
并尝试从中获取随机项,因此:

console.log(_.sample(numbers, 5));
这将以随机顺序从数组中获得5个随机数(字符串),如:

"17", "2", "3", "18", "10"
如何获得排序列表或随机项,如

"2", "3", "10", "17", "18"
\示例
可能不是这里的最佳选择。我试图从给定数组中获取随机项,并从数组的左到右拾取这些项

如何在JavaScriptp中实现这一点

多谢各位

编辑:我有一个字符串数组,而不是数字,因此我无法对随机挑选的项目进行排序

EDIT2:为了避免混淆,数组中有单词(=字符串),我使用了这些数字作为字符串,以更容易地演示我试图实现的目标。(很抱歉可能会混淆)

您可以使用对返回的数组进行排序:

更好的随机方法是:

var randomChoice = numbers[~~(Math.random() * numbers.length)]
注意:在本上下文中,
~
执行与
Math.floor()
相同的操作。它们可以互换

总而言之:

var numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18"];

var randomSample = []

for(var i=0; i < 5; i++) {
   var randomChoice = numbers[~~(Math.random() * numbers.length)]
   randomSample.push(randomChoice)
}

var sortedRandomSample = randomSample.sort(function(a, b) { return parseInt(a, 10) - parseInt(b, 10) })
var编号=[“1”、“2”、“3”、“4”、“5”、“6”、“7”、“8”、“9”、“10”、“11”、“12”、“13”、“14”、“15”、“16”、“17”、“18”];
var randomSample=[]
对于(变量i=0;i<5;i++){
var randomChoice=numbers[~~(Math.random()*numbers.length)]
随机样本。推送(随机选择)
}
var sortedRandomSample=randomSample.sort(函数(a,b){return parseInt(a,10)-parseInt(b,10)})

演示:

为什么不实现自己的sample方法,然后在调用xample.sample后调用方法sort?

这里有一个解决方案,它不假设原始顺序。其思想是查找元素在原始数组中的位置并按其排序。但是,这假设每个元素都是唯一的

sample.sort(function(a, b) {
    return numbers.indexOf(a) - numbers.indexOf(b);
});
对于大型阵列,这也会非常缓慢。

尝试以下方法:

function random(array, elements) {
   return array.concat().sort(function() {
     if (Math.random() < 0.5) {
       return -1;
     } else {
       return 1;
     }
   }).slice(0, elements).sort(
     function(a, b) {
       return a - b
     });
}
函数随机(数组、元素){
返回array.concat().sort(函数(){
if(Math.random()<0.5){
返回-1;
}否则{
返回1;
}
}).slice(0,元素)。排序(
功能(a、b){
返回a-b
});
}
这是小提琴:


我能想到的最简单的方法如下:

var randomSample = _.sample(numbers.map(function(v,i){ return i; }), 5)
                    .sort(function(a,b){ return a-b; })
                    .map(function(v){ return numbers[v]; });
也就是说,创建一个临时数组,该数组保存原始数组的索引,即仅包含数字
0
numbers.length-1
):

从该数组中随机抽取一个样本:

对样本进行排序:

sampleIndices.sort(function(a,b){ return a-b; })
然后使用排序后的随机选择索引从原始数组中获取值:

var randomSample = sampleIndices.map(function(v){ return numbers[v]; });
如我的答案开头所示,您可以在一行中完成所有操作,而无需使用
索引
样本索引
变量。虽然如果要定期从相同的
数字
数组中采集样本,保留
索引
变量可能会有意义,以避免每次重新构建它,尤其是在原始数组相当大的情况下


无论原始数组中的值是什么类型的,这都将起作用,因为一旦选择了随机索引,这些值将在最后被选择出来。

这是一个没有排序的建议,并对所选项目使用辅助数组
random

首先获取一个空数组,然后用
true
填充,直到
count
元素被填充,然后用随机选择的位置过滤原始数组

此解决方案适用于给定数组的任何内容,无需使用indexOf进行排序或查找

函数getSortedRandom(数组、计数){ var random=array.map(函数(){return false;}), R 同时(计数){ r=Math.floor(Math.random()*array.length); if(!random[r]){ 随机[r]=真; 计数--; } } 返回array.filter(函数(\ui){ 返回随机[i]; }); } var random=getSortedRandom([“1”、“2”、“3”、“4”、“5”、“6”、“7”、“8”、“9”、“10”、“11”、“12”、“13”、“14”、“15”、“16”、“17”、“18”],5);
document.write(''+JSON.stringify(random,0,4)+'')从lodash 4.0.0开始,您可以将
采样功能与
排序
结合使用:

var编号=[“1”、“2”、“3”、“4”、“5”、“6”、“7”、“8”、“9”、“10”、“11”、“12”、“13”、“14”、“15”、“16”、“17”、“18”];
var randomSample=u.sampleSize(数字,5.sort();
控制台日志(随机样本)

包含数字的字符串也可以很容易地按数字排序。或者数字串只是一个例子?在上面的例子中,我在那里使用数字是因为更容易演示我想要做的事情-数组中是字符串(单词)。这看起来更像是注释而不是答案。for循环可能会选择相同的元素五次。你是对的。这就是随机选择的本质@但那不是OP想要的。他们显然希望随机选择五个不同的元素。@nnnnnn如果OP要求,可以稍作更改,从数字数组中删除所选元素,以确保所有选择都不同。注意:如果需要在代码中添加注释,则可读性不够:D,我会使用Math.floor,而不是试图变得太聪明,但是…这会修改原始数组,并以随机顺序返回所选元素。OP不想做这两件事。它不会修改原始数组,请检查小提琴。是的,它返回了一个随机顺序数组,这是我的错误。它确实修改了原始数组。添加
console.log(数字)调用函数后,您会看到。我认为复杂性将是O(n²logn)。如果您想改进这一点,可以创建一个哈希,使用字符串作为键,索引作为值。如果在排序之前执行此操作并使用哈希而不是
indexOf
,它将再次使其成为O(n log n)。
var sampleIndices = _.sample(indices, 5)
sampleIndices.sort(function(a,b){ return a-b; })
var randomSample = sampleIndices.map(function(v){ return numbers[v]; });