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

时间:2016-04-24 00:34:28

标签: 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", "3", "10", "17", "18"

_.sample可能不是这里的最佳选择。我试图从给定的数组中获取随机项目,并从阵列的左侧到右侧拾取这些项目。

如何在javascritp中执行此操作?

谢谢。

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

EDIT2:为了避免混淆,在数组中是单词(=字符串),我使用数字作为字符串来更容易地演示我想要实现的内容。 (抱歉可能存在混淆)

7 个答案:

答案 0 :(得分:3)

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

_.sample(numbers, 5).sort(function(a, b) { return parseInt(a, 10) - parseInt(b, 10) })

更好的随机是:

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) })

演示:https://jsbin.com/zosizefaga/edit?html,js,console,output

答案 1 :(得分:1)

这是一个没有对原始订单做出任何假设的解决方案。我们的想法是在原始数组中查找元素的位置并按此排序。但是,假设每个元素都是唯一的。

sample.sort(function(a, b) {
    return numbers.indexOf(a) - numbers.indexOf(b);
});

对于大型阵列,这也很慢。

答案 2 :(得分:0)

为什么不实现自己的样本方法,在调用_.sample之后调用方法sort?

答案 3 :(得分:0)

试试这个:

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
     });
}

这是小提琴:

JSFiddle

答案 4 :(得分:0)

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

var randomSample = _.sample(numbers.map(function(v,i){ return i; }), 5)
                    .sort(function(a,b){ return a-b; })
                    .map(function(v){ return numbers[v]; });

也就是说,创建一个包含原始数组索引的临时数组,即只有数字0numbers.length - 1):

var indices = numbers.map(function(v,i){ return i; })

那个数组中随机抽样:

var sampleIndices = _.sample(indices, 5)

对样本进行排序:

sampleIndices.sort(function(a,b){ return a-b; })

然后使用已排序的随机选择的索引从原始数组中获取值:

var randomSample = sampleIndices.map(function(v){ return numbers[v]; });

如我的答案开头所示,您可以在不使用indicessampleIndices变量的情况下在一行中完成所有操作。虽然如果你要定期从同一个numbers数组中取样,那么保持indices变量以保存每次重建它可能是有意义的,特别是如果原始数组非常大的话。 / p>

无论原始数组中的值是什么类型,都可以使用,因为一旦选择了随机索引,这些值就会在最后被选中。

答案 5 :(得分:0)

这是一个没有排序的提案,并为所选项目使用辅助数组random

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

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

&#13;
&#13;
function getSortedRandom(array, count) {
    var random = array.map(function () { return false; }),
        r;

    while (count) {
        r = Math.floor(Math.random() * array.length);
        if (!random[r]) {
            random[r] = true;
            count--;
        }
    }
    return array.filter(function (_, i) {
        return random[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('<pre>' + JSON.stringify(random, 0, 4) + '</pre>');
&#13;
&#13;
&#13;

答案 6 :(得分:0)

从lodash 4.0.0开始,您可以将_.sampleSize功能与sort结合使用:

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

var randomSample = _.sampleSize(numbers, 5).sort();

console.log(randomSample);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
&#13;
&#13;
&#13;