javascript - 如何在javascript中有效地从Array中选择两个随机索引而不会重复?
问题描述
我有一个数组数组,我需要选择 (index1, index2) 的 2 个随机和不同的组合
让我举个例子
data = [["a", "b", "c", "d"], ["e", "g"], ["i", "j", "k"]]
我需要有 (index1: 0 , index2: 2) 和 (index1: 2 , index2: 1)
我怎样才能有效地做到这一点?
解决方案
首先,您可以创建一个组合:
const i11 = Math.floor(Math.random() * data.length);
const i12 = Math.floor(Math.random() * data[i11].length);
然后您可以检查内部数组是否只有一个元素。如果它只有一个元素并且是第一个组合,则应在以下步骤中忽略它:
const dataLength = data[i11].length > 1 ? data.length : data.length - 1;
现在您可以为第二个组合生成外部索引并对其进行调整:
let i21 = Math.floor(Math.random() * dataLength);
if (i21 >= i11 && data[i11].length === 1) ++i21;
接下来可以检查第一个组合的外部索引和第二个组合的外部索引是否相同,并进行相同的调整以避免重复:
const innerDataLength = i21 === i11 ? data[i21].length - 1 : data[i21].length;
最后你可以生成第二个内部索引并调整它
let i22 = Math.floor(Math.random() * innerDataLength);
if (i21 === i11 && i22 >= i12) ++i22;
整个代码作为一个带有测试的函数:
const data = [["a", "b", "c", "d"], ["e", "g"], ["i", "j", "k"]];
function combinations(data) {
const i11 = Math.floor(Math.random() * data.length);
const i12 = Math.floor(Math.random() * data[i11].length);
const dataLength = data[i11].length > 1 ? data.length : data.length - 1;
let i21 = Math.floor(Math.random() * dataLength);
if (i21 >= i11 && data[i11].length === 1) ++i21;
const innerDataLength = i21 === i11 ? data[i21].length - 1 : data[i21].length;
let i22 = Math.floor(Math.random() * innerDataLength);
if (i21 === i11 && i22 >= i12) ++i22;
return [[i11, i12], [i21, i22]];
}
console.log(combinations(data));
for (let i = 0; i < 10000; ++i) {
const [[i11, i12], [i21, i22]] = combinations(data);
if (i11 === i21 && i12 == i22) console.log('Test failed!');
}
推荐阅读
- php - Laravel 急切加载问题。如何修复收到的 N+1 警告?
- android - 录像模式屏幕不适合手机屏幕
- c# - 非常大的文件上传到 webDAV 会导致 tomcat OOM 错误
- wordpress - 如何修复 Wordpress 的“您的网站出现严重错误”
- javascript - 带有承诺链的nodejs类的单元测试
- openid-connect - OIDC 1.0 声明的大小和数量是否有限制?
- c# - 构建后不加载 WPF 图像
- reactjs - 从 Mongodb 字符串中反应电话卡文本并且没有看到换行符
- reactjs - 无法在 React 中呈现我的数组:收到错误“预期分配或函数调用,而是看到一个表达式”
- c - 有人可以向我解释这段代码是如何工作的吗?