1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Collections open source project
//
// Copyright (c) 2021 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//
// Note: This comes from swift-algorithms.
extension Collection {
/// Randomly selects the specified number of elements from this collection,
/// maintaining their relative order.
///
/// - Parameters:
/// - k: The number of elements to randomly select.
/// - rng: The random number generator to use for the sampling.
/// - Returns: An array of `k` random elements. If `k` is greater than this
/// collection's count, then this method returns the full collection.
///
/// - Complexity: O(*n*), where *n* is the length of the collection.
@inlinable
public func randomStableSample<G: RandomNumberGenerator>(
count k: Int, using rng: inout G
) -> [Element] {
guard k > 0 else { return [] }
var remainingCount = count
guard k < remainingCount else { return Array(self) }
var result: [Element] = []
result.reserveCapacity(k)
var i = startIndex
var countToSelect = k
while countToSelect > 0 {
let r = Int.random(in: 0..<remainingCount, using: &rng)
if r < countToSelect {
result.append(self[i])
countToSelect -= 1
}
formIndex(after: &i)
remainingCount -= 1
}
return result
}
/// Randomly selects the specified number of elements from this collection,
/// maintaining their relative order.
///
/// This method is equivalent to calling `randomStableSample(k:using:)`,
/// passing in the system's default random generator.
///
/// - Parameter k: The number of elements to randomly select.
/// - Returns: An array of `k` random elements. If `k` is greater than this
/// collection's count, then this method returns the full collection.
///
/// - Complexity: O(*n*), where *n* is the length of the collection.
@inlinable
public func randomStableSample(count k: Int) -> [Element] {
var g = SystemRandomNumberGenerator()
return randomStableSample(count: k, using: &g)
}
}
|