2017-03-11 12 views
4

私はes6セットまたはマップに移動することを考えているオブジェクトの配列を使用するプロジェクトを持っています。es6のランダムな項目の取得方法マップまたは設定

私はすぐにそれらからランダムな項目を取得する必要があります(私の現在の配列では明らかに簡単です)。どうすればいい?

+0

セットとマップは、このようなランダムアクセス(キーがわからない場合)には適していません。あなたはキーや値を反復することになります。 [this](http://stackoverflow.com/q/37822141/5459839)および[this](http://stackoverflow.com/q/30921283/5459839)を参照してください。 – trincot

答えて

4

マップとセットは、ランダムアクセスにはあまり適していません。それらは順序付けられており、その長さは分かっていますが、それらは順序指数によるアクセスのために索引付けされていません。したがって、MapまたはSetでN番目のアイテムを取得するには、そのアイテムを見つけるためにそれを反復処理する必要があります。

セットまたはマップからランダムなアイテムを取得する簡単な方法は、キー/アイテムのリスト全体を取得し、次にランダムなアイテムを選択することです。

// get random item from a Set 
function getRandomItem(set) { 
    let items = Array.from(set); 
    return items[Math.floor(Math.random() * items.length)]; 
} 

は、Setと、このような地図の両方で動作しますバージョン作ることができます:これは明らかに大規模なセットや地図でも実行することになりものではありません

// returns random key from Set or Map 
function getRandomKey(collection) { 
    let keys = Array.from(collection.keys()); 
    return keys[Math.floor(Math.random() * keys.length)]; 
} 

をランダムなものを選択するためには、すべてのキーを反復して一時的な配列を作成する必要があるからです。


地図とセットの両方が知られているサイズを持っているので、あなたも、純粋に.sizeプロパティに基づいてランダムなインデックスを選択することができ、あなたが希望N番目の項目になったまで、あなたは地図またはSetを繰り返し処理でき。大規模なコレクションの場合、これは少し速いかもしれませんし、平均的にはコレクションのサイズ/ 2に比例しますが、もう少しコードを犠牲にして一時的なキー配列を作成することは避けてください。

// returns random key from Set or Map 
function getRandomKey(collection) { 
    let index = Math.floor(Math.random() * collection.size); 
    let cntr = 0; 
    for (let key of collection.keys()) { 
     if (cntr++ === index) { 
      return key; 
     } 
    } 
} 
関連する問題