2017-03-11 55 views
4

我有一個項目使用了我正在考慮移至es6集合或地圖的對象數組。如何從es6中獲得隨機項目映射或設置

我需要快速從他們那裏得到一個隨機項目(對於我當前的數組顯然是微不足道的)。我將如何做到這一點?

+0

集合和貼圖不適合這種隨機訪問(如果您不知道密鑰)。你最終會迭代鍵或值。請參閱[this](http://stackoverflow.com/q/37822141/5459839)和[this](http://stackoverflow.com/q/30921283/5459839)。 – trincot

回答

4

地圖和集合不太適合隨機訪問。它們是有序的,它們的長度是已知的,但它們沒有被索引以便通過訂單索引訪問。因此,要獲取地圖或集合中的第N個項目,您必須遍歷它才能找到該項目。

從Set或Map中獲取隨機項目的簡單方法是獲取整個項目列表,然後選擇一個隨機項目。

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

你可以做一個版本,將與既有集和這樣的地圖工作:

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

這顯然不是東西會用大集或地圖表現良好因爲它必須迭代所有的鍵並構建一個臨時數組以便選擇一個隨機數。


因爲a地圖和一套具有已知大小,你也可以選擇在.size財產純粹基於隨機索引,然後你可以通過地圖迭代或設置直到你得到所需第N項。對於大集合來說,這可能會更快一些,並且會避免創建臨時數組,但會犧牲一點代碼的代價,但平均而言,它仍然會與集合的大小/ 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; 
     } 
    } 
}