3 回答

TA贡献1808条经验 获得超4个赞
一种解决方案是您将整个数组打乱,然后您只需根据需要选择每个数组中的元素数量。
这是示例(shuffle 函数是从How can I shuffle an array? 复制粘贴的?)
function shuffle(a) {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
function splitArrayRandomly(arr, sizes) {
const shuffledArr = shuffle(arr);
let pos = 0;
const arrays = sizes.map(size => {
const newArr = shuffledArr.slice(pos, pos + size);
pos += size;
return newArr;
});
return arrays;
}
const arr = [4, 7, 15, 22, 11, 6, 19];
// This option create 3 arrays, first of size 4, second of size 2 and last with size 1
const sizes = [4,2,1];
console.log(splitArrayRandomly(arr, sizes));
在您的情况下,您放入sizes这个数组[8, 8, 14],它会返回三个具有这些大小的数组。然后,如果需要,您可以将它们放入您arrCard, arrCent, arrSec的变量中。

TA贡献1789条经验 获得超10个赞
制作第二个数组,映射出数组的分布:
const dist = [8, 8, 14];
那将是 3 个数组——前两个数组的长度为 8,第三个数组的长度为 14。在演示中,该数组是第二个参数。
接下来,随机打乱主数组。在演示中,主数组是第一个参数。为了随机打乱主数组,我们将使用Fisher-Yates Shuffle
最后,for使用了两个循环。
外部循环将创建一个空数组。它将迭代 dist 数组的长度。在演示中,这将是三倍。
内部循环将.shift()* 从主数组中取出一个值(已随机重新排序(参见 #2)),然后.push()将其放入先前在外循环中定义的数组中(参见 #3.1)。每个内循环将迭代当前外循环迭代的索引位置指示的次数。
示例(伪代码)
/* On the second iteration of the outer loop, will be 8 */
dist[1] = 8
/* On the inner loop, it will take the values of the randomly reordered main
array in the range of 9 thru 16 */
["e9","i4","i10","s2","e8","i9","i3","i8"]
*.shift()将永久获取索引 0 处的数组值。这样做是为了使主数组中的值不会在子数组中重复
一旦内部循环的迭代完成,该数组将被.push()编辑到结果数组中。完成最后一个内部循环后,结果数组将作为二维数组返回。
示例(伪代码)
/* Returned as a two dimensional array */
result = [[8 values], [8 values], [14 values]]
/* Assign variables to each sub-array */
const cardArr = result[0];
const centArr = result[1];
const sectArr = result[2];
演示
const main = ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10', 'i1', 'i2', 'i3', 'i4', 'i5', 'i6', 'i7', 'i8', 'i9', 'i10', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'e10'];
const dist = [8, 8, 14];
function randomDistribution(array, dist) {
let total = array.length, split = dist.length;
let result = [], temp, index;
while(total) {
index = Math.floor(Math.random() * total--);
temp = array[total];
array[total] = array[index];
array[index] = temp;
}
for (let subIdx = 0; subIdx < split; subIdx++) {
let subArr = [];
for (let reIdx = 0; reIdx < dist[subIdx]; reIdx++) {
subArr.push(array.shift());
}
result.push(subArr);
}
return result;
}
let twoDArray = randomDistribution(main, dist);
console.log(JSON.stringify(twoDArray));
const cardArray = twoDArray[0];
const centArray = twoDArray[1];
const sectArray = twoDArray[2];
console.log(`cardArray: ${cardArray}`);
console.log(`centArray: ${centArray}`);
console.log(`sectArray: ${sectArray}`);
.as-console-row-code {
word-break: break-word;
overflow-x: hidden;
}

TA贡献1884条经验 获得超4个赞
1)从输入数组中,通过生成随机索引来创建随机顺序,并限制数组的大小。
2) 创建与大小数组相同长度的数组输出数组(初始化)。
3) 维护o_idx(输出索引)以跟踪需要推送元素的输出数组。
4)一旦获得r_idx(随机索引),然后将相应的值(arr[r_idx])推送到相应的输出数组(output[o_idx])。
const randomOrderInSizes = (arr, sizes) => {
const myRandom = () => Math.floor((Math.random() * 100) % arr.length);
const temp = [];
const output = sizes.map(() => []);
let o_idx = 0;
arr.forEach(() => {
let r_idx = myRandom();
while (temp.includes(r_idx)) {
r_idx = myRandom();
}
temp.push(r_idx);
if (sizes[o_idx] === output[o_idx].length) {
o_idx += 1;
}
output[o_idx].push(arr[r_idx]);
});
return output;
};
const data = [21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
const required = randomOrderInSizes(data, [8, 8, 14]);
console.log(required);
添加回答
举报