我正在尝试编写一个 TypeScript 函数来打乱数组。
默认情况下,我希望洗牌顺序是随机的(但受种子影响)。(我已经可以使用这个功能了function random(seed: number): number:)
但是,我还想允许通过每个项目的重量来影响订单。
换句话说,我希望默认项目权重为 1,如果一个项目的权重为 10,那么它在打乱顺序中较早出现的可能性应该增加 10 倍。
我是否正确地思考过这个问题?这是一个合理的目标吗?
我认为我需要使用 Fisher-Yates 算法,但适应于与主数组长度相同的权重数组,并且主数组将被洗牌,以便较高权重的项目更有可能首先出现。
function removeDuplicates<T>(array: T[]): T[] {
const uniqueValues = new Set<T>();
return array.filter((item) => {
if (!uniqueValues.has(item)) {
uniqueValues.add(item);
return true;
}
return false;
});
}
function duplicateItemsBasedOnWeights<T>(array: T[], weights: number[]): T[] {
const result = [];
for (const [index, element] of array.entries()) {
for (let position = 0; position < weights[index]; position++) {
result.push(element);
}
}
return result;
}
export function …Run Code Online (Sandbox Code Playgroud) 有一个包含 ID 和这些 ID 的权重的哈希值。
y = { 1 => 0.7, 2 => 0.2, 3 => 0.1 }
Run Code Online (Sandbox Code Playgroud)
我想根据权重对这个哈希值进行洗牌。
我尝试了多种不同的方法,所有这些都给我带来了相似的、意想不到的结果。这是我发现的最简洁的。
y.sort_by {|v| -v[1]*rand()}
Run Code Online (Sandbox Code Playgroud)
当我运行此一万次并选出第一个 ID 时,我得到以下计数:
{1=>8444, 2=>1316, 3=>240}
Run Code Online (Sandbox Code Playgroud)
我希望这些计数能够反映上面的权重(例如1=> 7000)。我有点不清楚为什么这种洗牌与这些权重不匹配。有人可以消除我的困惑并告诉我如何解决它吗?
以下是我发现的一些有用的来源: