Shy*_*xit 66 html javascript arrays jquery
我正在研究'如何在javascript中从数组中随机访问元素'.我找到了很多相关的链接.喜欢: 从JavaScript数组中获取随机项
var item = items[Math.floor(Math.random()*items.length)];
Run Code Online (Sandbox Code Playgroud)
问题:但是在这里我们只能从数组中选择一个项目.如果我们想要多个元素,那么我们怎样才能实现这个.所以请从这个语句中我们如何从数组中获得多个元素.
Abd*_*UMI 128
只有两行:
// Shuffle array
const shuffled = array.sort(() => 0.5 - Math.random());
// Get sub-array of first n elements after shuffled
let selected = shuffled.slice(0, n);
Run Code Online (Sandbox Code Playgroud)
Ber*_*rgi 60
尝试这种非破坏性(和快速)功能:
function getRandom(arr, n) {
var result = new Array(n),
len = arr.length,
taken = new Array(len);
if (n > len)
throw new RangeError("getRandom: more elements taken than available");
while (n--) {
var x = Math.floor(Math.random() * len);
result[n] = arr[x in taken ? taken[x] : x];
taken[x] = --len in taken ? taken[len] : len;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
Ola*_*nle 27
这里有一个单线独特的解决方案
array.sort(() => Math.random() - Math.random()).slice(0, n)
Run Code Online (Sandbox Code Playgroud)
Lau*_*kas 11
创建一个功能:
var getMeRandomElements = function(sourceArray, neededElements) {
var result = [];
for (var i = 0; i < neededElements; i++) {
result.push(sourceArray[Math.floor(Math.random()*sourceArray.length)]);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
您还应该检查sourceArray是否有足够的元素要返回.如果要返回唯一元素,则应从sourceArray中删除所选元素.
nod*_*ejh 10
lodash _.sample
和_.sampleSize
.
从集合到集合大小的唯一键处获取一个或 n 个随机元素。
_.sample([1, 2, 3, 4]);
// => 2
_.sampleSize([1, 2, 3], 2);
// => [3, 1]
_.sampleSize([1, 2, 3], 3);
// => [2, 3, 1]
Run Code Online (Sandbox Code Playgroud)
在不更改原始数组的情况下获取5个随机项:
const n = 5;
const sample = items
.map(x => ({ x, r: Math.random() }))
.sort((a, b) => a.r - b.r)
.map(a => a.x)
.slice(0, n);
Run Code Online (Sandbox Code Playgroud)
(不要将此用于大型列表)
如果您想在循环中从数组中随机获取项目而不重复,您可以使用splice
以下命令从数组中删除所选项目:
var items = [1, 2, 3, 4, 5];
var newItems = [];
for (var i = 0; i < 3; i++) {
var idx = Math.floor(Math.random() * items.length);
newItems.push(items[idx]);
items.splice(idx, 1);
}
console.log(newItems);
Run Code Online (Sandbox Code Playgroud)
ES6 语法
const pickRandom = (arr,count) => {
let _arr = [...arr];
return[...Array(count)].map( ()=> _arr.splice(Math.floor(Math.random() * _arr.length), 1)[0] );
}
Run Code Online (Sandbox Code Playgroud)
.sample
从Python标准库移植:
function sample(population, k){
/*
Chooses k unique random elements from a population sequence or set.
Returns a new list containing elements from the population while
leaving the original population unchanged. The resulting list is
in selection order so that all sub-slices will also be valid random
samples. This allows raffle winners (the sample) to be partitioned
into grand prize and second place winners (the subslices).
Members of the population need not be hashable or unique. If the
population contains repeats, then each occurrence is a possible
selection in the sample.
To choose a sample in a range of integers, use range as an argument.
This is especially fast and space efficient for sampling from a
large population: sample(range(10000000), 60)
Sampling without replacement entails tracking either potential
selections (the pool) in a list or previous selections in a set.
When the number of selections is small compared to the
population, then tracking selections is efficient, requiring
only a small set and an occasional reselection. For
a larger number of selections, the pool tracking method is
preferred since the list takes less space than the
set and it doesn't suffer from frequent reselections.
*/
if(!Array.isArray(population))
throw new TypeError("Population must be an array.");
var n = population.length;
if(k < 0 || k > n)
throw new RangeError("Sample larger than population or is negative");
var result = new Array(k);
var setsize = 21; // size of a small set minus size of an empty list
if(k > 5)
setsize += Math.pow(4, Math.ceil(Math.log(k * 3, 4)))
if(n <= setsize){
// An n-length list is smaller than a k-length set
var pool = population.slice();
for(var i = 0; i < k; i++){ // invariant: non-selected at [0,n-i)
var j = Math.random() * (n - i) | 0;
result[i] = pool[j];
pool[j] = pool[n - i - 1]; // move non-selected item into vacancy
}
}else{
var selected = new Set();
for(var i = 0; i < k; i++){
var j = Math.random() * (n - i) | 0;
while(selected.has(j)){
j = Math.random() * (n - i) | 0;
}
selected.add(j);
result[i] = population[j];
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
从Lib/random.py移植的实现.
笔记:
setsize
基于Python中的特性来设置效率.虽然它尚未针对JavaScript进行调整,但算法仍将按预期运行.Array.prototype.sort
.然而,该算法保证在有限时间内终止.Set
实现的旧版浏览器,该集可以替换为a Array
并.has(j)
替换为.indexOf(j) > -1
.针对公认答案的表现:
我不敢相信没有人没有提到这个方法,非常干净和简单。
const getRnd = (a, n) => new Array(n).fill(null).map(() => a[Math.floor(Math.random() * a.length)]);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
46360 次 |
最近记录: |