(array: readonly T[], count: number, rng: SeededRandom | { next(): number })
| 58 | * @returns @zh 采样结果 @en Sample result |
| 59 | */ |
| 60 | export function sample<T>(array: readonly T[], count: number, rng: SeededRandom | { next(): number }): T[] { |
| 61 | if (count > array.length) { |
| 62 | throw new Error('Sample count exceeds array length'); |
| 63 | } |
| 64 | |
| 65 | if (count === array.length) { |
| 66 | return shuffleCopy(array, rng); |
| 67 | } |
| 68 | |
| 69 | // For small sample sizes relative to array, use selection |
| 70 | if (count < array.length / 2) { |
| 71 | const result: T[] = []; |
| 72 | const indices = new Set<number>(); |
| 73 | |
| 74 | while (result.length < count) { |
| 75 | const index = Math.floor(rng.next() * array.length); |
| 76 | if (!indices.has(index)) { |
| 77 | indices.add(index); |
| 78 | result.push(array[index]); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | return result; |
| 83 | } |
| 84 | |
| 85 | // For large sample sizes, shuffle and take first N |
| 86 | return shuffleCopy(array, rng).slice(0, count); |
| 87 | } |
| 88 | |
| 89 | /** |
| 90 | * @zh 从数组中随机采样 N 个元素(可重复) |
no test coverage detected