如何在 Javascript 中从数组中获取元素的随机组合?



我看到许多函数给出数组中的单个随机元素或所有元素组合,但我试图找出每次都返回随机组合的东西。

ex) let array1 = ["mike", "ted","bill","mark"];
sample outputs would be like this 
output1 = mike, ted
output2= ted
output3 = mark,ted,bill,mike
output4 = mike, bill

它可以是所有元素,也可以只是一个随机元素。

复制原始数组。生成一个介于 1 和副本长度之间的随机数 n,然后循环 n 次以从复制的数组 n 次中获取随机索引。这就是您获得"名称"值的地方。确保每次都拼接复制的数组以避免重复:

更新:

在执行其余代码之前,我添加了一行Array.slice()来复制原始数组:

let array1 = ["mike", "ted","bill","mark"];
let arrCopy = array1.slice()
let ranIdx
let resArr = []
let ranLen = Math.floor(Math.random() * arrCopy.length) + 1
for(i=0; i < ranLen; i++){
ranIdx = Math.floor(Math.random() * arrCopy.length)
resArr.push(arrCopy.splice(ranIdx,1)[0])  
}
console.log(resArr)

也许是这样的:

let array1 = ["mike", "ted","bill","mark"];
function get_random_in_range(_min, _max) {
_min = Math.ceil(_min);
_max = Math.floor(_max);
return Math.floor(Math.random() * (_max - _min + 1)) + _min;
}
function get_randoms(_arr){
	var out = [];
	var count_of_rnd_out = get_random_in_range(0, _arr.length-1);
	for (var i = 0; i < count_of_rnd_out+1; i++) {
		var rnd_el_index = get_random_in_range(0, _arr.length-1);
		var rnd_el = _arr[rnd_el_index];
		while(out.indexOf(rnd_el) >= 0) {    /* for exclude duplicates */
		  rnd_el_index = get_random_in_range(0, _arr.length-1);
		  rnd_el = _arr[rnd_el_index];
	    }
		out.push(rnd_el);
	}
	return out;
}
console.log(get_randoms(array1));

也许这个包可能很有用

通过使用此代码

cmb = Combinatorics.power(['a','b','c']);

它将生成数组的所有组合。然后,您可以生成一个介于 0 和数组长度(含)之间的数字来选择随机输出。

我会把它写在一个函数上,该函数部分洗牌一个数组,从中返回前n个元素的随机选择。 此外,我会随机选择要选择的元素数量。 我们可以用边界("从列表中选择 1 到 3 个元素")或不使用边界("从 1 到 list.length 元素中挑选")来做到这一点。

这两个选项都显示在这里,anyRandomSubset构建在randomSubset之上,这需要边界。 如果不需要边界,我们可以很容易地跳过中介。

下面是一个实现:

const {random, floor} = Math
const excluding = (i) => (xs) => 
[... xs .slice (0, i), ... xs .slice (i + 1)]
const partialShuffle = (n) => (xs, i = floor(random () * xs .length)) =>
n <= 0 || n > xs .length || xs .length == 0
? []
: [xs[i], ... partialShuffle (n - 1) (excluding (i) (xs))]
const randomSubset = (lo, hi) => (xs) =>
partialShuffle (floor (random () * (hi - lo + 1) + lo)) (xs)
const anyRandomSubset = (xs) => 
randomSubset (1, xs .length) (xs)
for (var i = 0; i < 20; i++) {
console .log (anyRandomSubset (["mike", "ted","bill","mark"]))
}
.as-console-wrapper {min-height: 100% !important; top: 0}

partialShuffle是这个完整随机播放函数的变体:

const shuffle = (xs, i = floor(random () * xs.length)) =>
xs.length == 0
? []
: [xs[i], ... shuffle (excluding (i) (xs))]

这是数组最常见的真实洗牌的递归公式,即费舍尔-耶茨算法。 如果我们将其用于长数组(或上面部分版本中的大n,则此递归版本会遇到递归深度问题。 但对于小型阵列来说可能没问题。

请注意,partialShuffle及其帮助程序函数excluding都是有用的实用程序函数。 只有randomSubsetanyRandomSubset特定于此问题。

最新更新