如何在没有 item/coordinate 重复项的情况下选择二维矩阵的 N 个随机元素的 col/row 或 x/y 坐标?
How does one pick the col/row or x/y coordinates of N random elements of a 2D matrix without item/coordinate duplicates?
我有一个二维矩阵,下面是一个例子data = [["a", "b", "c", "d"], ["e", "g"], ["i", "j", "k"]]
我需要得到 N 个没有重复的随机 (x, y)
索引。
我已经问了一个不同的问题相同的上下文,这是选择 2 x,y 组合的解决方案
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!');
}
function pickNOf(list, n) {
// - create a new shallow array copy.
// - does decouple the original reference, thus it
// prevents its further mutation by e.g. `splice`.
list = Array.from(list);
// - creates and returns an array of the desired length
// by a mapping task which constantly slices random
// items from the shallow array copy.
return Array.from({ length: n }, () => list.splice(
// - `splice` does mutate the list by removing a
// single item from its randomly chosen index.
Math.floor(Math.random() * list.length), 1
)[0]);
}
function pickNUniqueItemsFromNestedArray(arr, n) {
// - flatten nested array structure,
// - channel it through a `Set` in order
// to keep just unique values,
// - return the result of the forwarded
// `pickNOf` call.
return pickNOf([...new Set(
arr.flat(Infinity)
)], n);
}
const data = [
["a", "b", "c", "d"],
["e", "g"],
["i", "j", "k"]
];
console.log(
"pickNUniqueItemsFromNestedArray(data, 9) ...",
pickNUniqueItemsFromNestedArray(data, 9)
);
console.log(
"pickNUniqueItemsFromNestedArray(data, 5) ...",
pickNUniqueItemsFromNestedArray(data, 5)
);
console.log(
"pickNUniqueItemsFromNestedArray(data, 3) ...",
pickNUniqueItemsFromNestedArray(data, 3)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
编辑 由于...
Thank you it works, but i need indexes –
Amine
But that's not what the question's topic doe state ... "How to pick N random elements from a 2D matrix without duplicates in javascript?" Nevertheless I will provide a second solution which utilizes the first given approach in order to fully meet the OP's requirements. –
Peter Seliger
为了满足 OP 的要求,上面给出的方法略微更改为 ...
function pickNOf(list, n) {
// - create a new shallow array copy.
// - does decouple the original reference, thus it
// prevents its further mutation by e.g. `splice`.
list = Array.from(list);
// - creates and returns an array of the desired length
// by a mapping task which constantly slices random
// items from the shallow array copy.
return Array.from({ length: n }, () => list.splice(
// - `splice` does mutate the list by removing a
// single item from its randomly chosen index.
Math.floor(Math.random() * list.length), 1
)[0]);
}
function pickNUniqueIndexTuplesFrom2dMatrix(matrix, n) {
// - create a flat array of any of a
// matrix' index coordinates/tuples.
return pickNOf(
matrix.flatMap((arr, rowIdx) =>
arr.map((_, colIdx) => [rowIdx, colIdx])
), n
);
}
const data = [
["a", "b", "c", "d"],
["e", "g"],
["i", "j", "k"]
];
console.log(
"pickNUniqueIndexTuplesFrom2dMatrix(data, 9) ...",
pickNUniqueIndexTuplesFrom2dMatrix(data, 9)
);
console.log(
"pickNUniqueIndexTuplesFrom2dMatrix(data, 5) ...",
pickNUniqueIndexTuplesFrom2dMatrix(data, 5)
);
console.log(
"pickNUniqueIndexTuplesFrom2dMatrix(data, 3) ...",
pickNUniqueIndexTuplesFrom2dMatrix(data, 3)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
备注
尽管或什至可能因为误解,基本方法本身并没有改变这一点可能会变得更加清楚。这是... 从数组中挑选 n
个没有重复项的随机项目 ... 和 ...
将主要任务拆分为更专业的子任务。 (如pickNOf
的实现演示,完美解决单个问题,无需重构。)
另一个 task/s has/have 以一种可以将输入数据传递给从没有重复的数组(希望通过两种不同的方法得到证明,每种方法针对不同的要求)。
我有一个二维矩阵,下面是一个例子data = [["a", "b", "c", "d"], ["e", "g"], ["i", "j", "k"]]
我需要得到 N 个没有重复的随机 (x, y)
索引。
我已经问了一个不同的问题相同的上下文,这是选择 2 x,y 组合的解决方案
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!');
}
function pickNOf(list, n) {
// - create a new shallow array copy.
// - does decouple the original reference, thus it
// prevents its further mutation by e.g. `splice`.
list = Array.from(list);
// - creates and returns an array of the desired length
// by a mapping task which constantly slices random
// items from the shallow array copy.
return Array.from({ length: n }, () => list.splice(
// - `splice` does mutate the list by removing a
// single item from its randomly chosen index.
Math.floor(Math.random() * list.length), 1
)[0]);
}
function pickNUniqueItemsFromNestedArray(arr, n) {
// - flatten nested array structure,
// - channel it through a `Set` in order
// to keep just unique values,
// - return the result of the forwarded
// `pickNOf` call.
return pickNOf([...new Set(
arr.flat(Infinity)
)], n);
}
const data = [
["a", "b", "c", "d"],
["e", "g"],
["i", "j", "k"]
];
console.log(
"pickNUniqueItemsFromNestedArray(data, 9) ...",
pickNUniqueItemsFromNestedArray(data, 9)
);
console.log(
"pickNUniqueItemsFromNestedArray(data, 5) ...",
pickNUniqueItemsFromNestedArray(data, 5)
);
console.log(
"pickNUniqueItemsFromNestedArray(data, 3) ...",
pickNUniqueItemsFromNestedArray(data, 3)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
编辑 由于...
Thank you it works, but i need indexes – Amine
But that's not what the question's topic doe state ... "How to pick N random elements from a 2D matrix without duplicates in javascript?" Nevertheless I will provide a second solution which utilizes the first given approach in order to fully meet the OP's requirements. – Peter Seliger
为了满足 OP 的要求,上面给出的方法略微更改为 ...
function pickNOf(list, n) {
// - create a new shallow array copy.
// - does decouple the original reference, thus it
// prevents its further mutation by e.g. `splice`.
list = Array.from(list);
// - creates and returns an array of the desired length
// by a mapping task which constantly slices random
// items from the shallow array copy.
return Array.from({ length: n }, () => list.splice(
// - `splice` does mutate the list by removing a
// single item from its randomly chosen index.
Math.floor(Math.random() * list.length), 1
)[0]);
}
function pickNUniqueIndexTuplesFrom2dMatrix(matrix, n) {
// - create a flat array of any of a
// matrix' index coordinates/tuples.
return pickNOf(
matrix.flatMap((arr, rowIdx) =>
arr.map((_, colIdx) => [rowIdx, colIdx])
), n
);
}
const data = [
["a", "b", "c", "d"],
["e", "g"],
["i", "j", "k"]
];
console.log(
"pickNUniqueIndexTuplesFrom2dMatrix(data, 9) ...",
pickNUniqueIndexTuplesFrom2dMatrix(data, 9)
);
console.log(
"pickNUniqueIndexTuplesFrom2dMatrix(data, 5) ...",
pickNUniqueIndexTuplesFrom2dMatrix(data, 5)
);
console.log(
"pickNUniqueIndexTuplesFrom2dMatrix(data, 3) ...",
pickNUniqueIndexTuplesFrom2dMatrix(data, 3)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
备注
尽管或什至可能因为误解,基本方法本身并没有改变这一点可能会变得更加清楚。这是... 从数组中挑选 n
个没有重复项的随机项目 ... 和 ...
将主要任务拆分为更专业的子任务。 (如
pickNOf
的实现演示,完美解决单个问题,无需重构。)另一个 task/s has/have 以一种可以将输入数据传递给从没有重复的数组(希望通过两种不同的方法得到证明,每种方法针对不同的要求)。