最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - Javascript - how to pick random elements from an array in order? - Stack Overflow

programmeradmin3浏览0评论

I have an array

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

and trying to get random items from it, so:

console.log(_.sample(numbers, 5));

this will give me 5 random numbers (strings) from the array in a random order, like:

"17", "2", "3", "18", "10"

How do I get a sorted list or random items, like?

"2", "3", "10", "17", "18"

_.sample will probably not be the best choice here. I am trying to get random items from a given array and have these items picked up from left to right of the array.

How to do this in javascritp?

Thank you.

EDIT: I have an array of strings, not numbers, so I cannot sort the randomly picked items.

EDIT2: To avoid confusing, in the array are words (= strings), I used there numbers as strings to more easily demonstrate what I am trying to achieve. (sorry for possible confusions)

I have an array

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

and trying to get random items from it, so:

console.log(_.sample(numbers, 5));

this will give me 5 random numbers (strings) from the array in a random order, like:

"17", "2", "3", "18", "10"

How do I get a sorted list or random items, like?

"2", "3", "10", "17", "18"

_.sample will probably not be the best choice here. I am trying to get random items from a given array and have these items picked up from left to right of the array.

How to do this in javascritp?

Thank you.

EDIT: I have an array of strings, not numbers, so I cannot sort the randomly picked items.

EDIT2: To avoid confusing, in the array are words (= strings), I used there numbers as strings to more easily demonstrate what I am trying to achieve. (sorry for possible confusions)

Share Improve this question edited Apr 24, 2016 at 0:46 user984621 asked Apr 24, 2016 at 0:34 user984621user984621 48.6k76 gold badges234 silver badges428 bronze badges 2
  • Strings that contain numbers can easily be sorted numerically too. Or are the strings of numbers just an example? – nnnnnn Commented Apr 24, 2016 at 0:37
  • In the example above, I used numbers there because of easier demonstration of what I want to do - in the array are strings (words). – user984621 Commented Apr 24, 2016 at 0:43
Add a ment  | 

7 Answers 7

Reset to default 3

You can use Array.prototype.sort to sort the returned array:

ie.

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

A better random would be:

var randomChoice = numbers[~~(Math.random() * numbers.length)]

Note: the ~~ performs the same action as Math.floor() in this context. They can be interchanged.

All together:

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

Demo: https://jsbin./zosizefaga/edit?html,js,console,output

Here is a solution that doesn't make any assumption about the original order. The idea is to lookup the element's position in the original array and sort by that. However, that assumes that every element is unique.

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

This will also be quite slow for large arrays.

Why don't you implement your own method of sample and after calling _.sample you call the method sort?

The easiest method I can think of is as follows:

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

That is, make a temporary array that holds the indices of the original array, i.e., just the numbers 0 through numbers.length - 1):

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

Take a random sample from that array:

var sampleIndices = _.sample(indices, 5)

Sort the sample:

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

Then use the sorted, randomly selected indices to get values out of the original array:

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

And as shown at the beginning of my answer, you can do it all in one line without using the indices and sampleIndices variables. Although if you are going to be regularly taking samples from the same numbers array it would probably make sense to keep the indices variable to save rebuilding it every time, especially if the original array is quite large.

This will work regardless of what type of values are in the original array, because those values are just selected out at the end once random indices have been selected.

Try this:

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

Here's the fiddle:

JSFiddle

This is a proposal without sorting and uses an helper array random for the selected items.

First get an empty array, then fill with true until count elements are filled and the filter the original array with the random selected positions.

This solution works for any content of the given array, without sort or lookup with indexOf.

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

As of lodash 4.0.0, you can use the _.sampleSize function in conjunction with sort:

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);
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>

发布评论

评论列表(0)

  1. 暂无评论