5

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.
4

7 に答える 7

4

(私にとって)明らかな方法は、配列をシャッフルしてから、最初の50個の要素を取得することです。 この質問には、配列をシャッフルするための良い方法があります。そうすればslice、最初の50個の要素をシャッフルできます。これにより、要素が一意になることが保証されます。

したがって、そこで関数を使用します。

fisherYates(text);
text = text.slice(0, 50);
于 2012-05-21T15:24:18.220 に答える
1

このトピックで説明されている優れたアルゴリズム(Cでは、JSでも同じことが簡単にできます)

于 2012-05-21T15:24:07.900 に答える
0

フィッシャー-イェーツアルゴリズムを調べてください。これでうまくいくと思います。

于 2012-05-21T15:24:21.537 に答える
0
var arr = [];
while(arr.length < 51){
    var ind = Math.floor(Math.random()*1000);
    if(!(ind in arr))
        arr.push(ind)
}

配列arrには50個のランダムな一意の番号があり、インデックスとして使用できます。

編集:

@ 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個の値が入力された配列

于 2012-05-21T15:29:53.223 に答える
0

一意の値を意味する場合:

デモ

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

一意のインデックスを意味する場合:

  • ランダムなインデックスを生成し、インデックスを配列に格納し、チェックを行って重複を防ぎます
  • 取得した配列の要素の削除を開始します (長さをキャッシュすると問題が発生する可能性があるため、しないでください)。
于 2012-05-21T15:27:47.603 に答える
0

これは、一意の値を持つインデックスではなく、ランダムなインデックスを意味すると想定しています。

1 つの方法は、配列をコピーして、使用する配列を削除することです。

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

もう 1 つの方法は、使用しているインデックスを追跡し、使用していないインデックスが見つかるまで探し続けることです。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);
于 2012-05-21T16:15:44.630 に答える
-2

Math.random() * 1000;

乱数を 50 個生成し、配列内の位置として使用します。

于 2012-05-21T15:22:26.793 に答える