2017-03-11 64 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; 
     } 
    } 
}