有userId可以hash取模

class MyClass {
    private featLimitConfigs: Map<string, any> = new Map([
        ['white_background', [{ count: 20, rate: 20, abTag: 'a' }, { count: 10, rate: 80, abTag: 'b' }]],
        ['sub_title', [{ count: 20, rate: 50, abTag: 'a' }, { count: 10, rate: 50, abTag: 'b' }]],
        ['generate_video', [{ count: 20, rate: 1 }]],
    ]);

    getAbTag(feature: string): string | undefined {
        const config = this.featLimitConfigs.get(feature);

        if (config) {
            // 计算总概率
            const totalRate = config.reduce((total, entry) => total + entry.rate, 0);

            // 生成哈希值并取模
            const hash = this.hashString(feature);
            const hashValue = hash % totalRate;

            // 根据哈希值找到对应的条目
            let cumulativeRate = 0;
            for (const entry of config) {
                cumulativeRate += entry.rate;
                if (hashValue < cumulativeRate) {
                    return entry.abTag;
                }
            }
        }

        // 如果找不到特征或配置无效,则返回 undefined
        return undefined;
    }

    private hashString(str: string): number {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = (hash << 5) - hash + char;
        }
        return hash;
    }
}

// 示例用法
const myInstance = new MyClass();
const abTag = myInstance.getAbTag('white_background');
console.log(abTag); // 输出:根据计算的概率为 'a' 或 'b'

正常可以直接随机概率

class MyClass {
    private featLimitConfigs: Map<string, any> = new Map([
        ['white_background', [{ count: 20, rate: 20, abTag: 'a' }, { count: 10, rate: 80, abTag: 'b' }]],
        ['sub_title', [{ count: 20, rate: 50, abTag: 'a' }, { count: 10, rate: 50, abTag: 'b' }]],
        ['generate_video', [{ count: 20, rate: 1 }]],
    ]);

    getAbTag(feature: string): string | undefined {
        const config = this.featLimitConfigs.get(feature);

        if (config) {
            // 计算总概率
            const totalRate = config.reduce((total, entry) => total + entry.rate, 0);

            // 生成在 0 到 totalRate 之间的随机数
            const randomValue = Math.random() * totalRate;

            // 根据随机值找到对应的条目
            let cumulativeRate = 0;
            for (const entry of config) {
                cumulativeRate += entry.rate;
                if (randomValue <= cumulativeRate) {
                    return entry.abTag;
                }
            }
        }

        // 如果找不到特征或配置无效,则返回 undefined
        return undefined;
    }
}

// 示例用法
const myInstance = new MyClass();
const abTag = myInstance.getAbTag('white_background');
console.log(abTag); // 输出:根据计算的概率为 'a' 或 'b'