2

別の配列から生成しているランダム配列に重複した値が含まれていないことを確認する方法を誰かがアドバイスできるかどうか疑問に思っていました.arr2に一意の値が含まれていることを確認したいですか?

JS

var limit = 5,
    i = 0,
    arr1 = [12, 14, 67, 45, 8, 45, 56, 8, 33, 89],
    arr2 = [];

    for ( i; i < limit; i++ ){
        var rand = Math.floor((Math.random()*9)+1);
        arr2.push( arr1[rand] );
    }

    console.log(arr2);

arr1[rand] と arr2[i] を比較する if ステートメントでしょうか。

4

5 に答える 5

6

一意の値のみを含むarr1のコピーである一時配列を作成します。

// Copy unique values in arr1 into temp_arr
var temp_obj = {}, temp_arr = [], i;
for(i = arr1.length; i--;)
    temp_obj[arr1[i]] = 1;
for(i in temp_obj) 
    temp_arr.push(i);

temp_arrその後、要素をに追加するたびに要素を削除できますarr2。コピー時にオブジェクトキーを使用したので、文字列があります。これを使用+して、にプッシュするときにそれらを数値に戻すことができarr2ます。

arr2.push(+temp_arr.splice(rand, 1)[0]);

また、乱数の選択方法を次のように変更する必要があります。

var rand = Math.floor(Math.random()*temp_arr.length);

コード全体:

var limit = 5,
  arr1 = [12, 14, 67, 45, 8, 45, 56, 8, 33, 89],
  arr2 = [],
  rand, 
  temp_obj = {},
  temp_arr = []
  i;

// Copy unique values from arr1 into temp_arr
for(i = arr1.length; i--;)
    temp_obj[arr1[i]] = 1;
for(i in temp_obj)
    temp_arr.push(i);;

// Move elements one at a time from temp_arr to arr2 until limit is reached
for (var i = limit; i--;){
    rand = Math.floor(Math.random()*temp_arr.length);
    arr2.push(+temp_arr.splice(rand, 1)[0]);
}

console.log(arr2);
于 2012-06-11T16:44:47.277 に答える
2

単純なO(n^2)解決策は、各要素をチェックして、配列内の他の位置に同じ値があるかどうかを確認することです。

線形時間ソリューションは、ハッシュセットデータ構造を使用して実現できます。オブジェクトを使用してJavaScriptで1つをハックできます。

var set = {};
set['0'] = true;
set['1'] = true;

if(set.hasOwnProperty('0')) {
    alert("duplicate 0!");
}

数値が整数で比較的小さい場合は、ブール値の配列でそれらを追跡できます。

于 2012-06-11T16:43:52.333 に答える
1

関数を使用してjQuery.inArray:)

var limit = 5,
arr1 = [12, 14, 67, 45, 8, 45, 56, 8, 33, 89],
l = arr1.length,
arr2 = [];

while( limit ){
      var tmp = arr1[  Math.random() * l | 0 ];  
      // for unsigned numbers '|0' construction works like Math.floor  
      if( !~$.inArray( tmp, arr2 ) ) { 
       // if not found $.inArray returns -1 ( == ~0 ), then !~-1 == true   
          limit--;
          arr2[ arr2.length ] = tmp;
      } 
} 
console.log( arr2 );
于 2012-06-11T19:25:56.297 に答える
1

これを試して

for ( i; i < limit; i++ ){
        var rand = Math.floor((Math.random()*9)+1);
        for(j=0; j <  arr1.length; j++)
           if(rand == arr1[j]
           { 
                blnfound = true;
                break;
           }
        if(!blnfound)
        arr2.push( arr1[rand] );
    }
于 2012-06-11T16:44:05.383 に答える
1

Fischer/Yates shuffle の詳細については、http://bost.ocks.org/mike/shuffle/を参照してください。あなたの問題では、シャッフルされたデックの最初の 5 つの要素を取ることができます。

于 2012-06-11T16:48:22.457 に答える