Skip to content

Instantly share code, notes, and snippets.

@khanhldt
Created April 16, 2016 09:38
Show Gist options
  • Save khanhldt/3bd25f20f169ee17cf04ae69b08621b8 to your computer and use it in GitHub Desktop.
Save khanhldt/3bd25f20f169ee17cf04ae69b08621b8 to your computer and use it in GitHub Desktop.
Extension to CollectionType and MutableCollectionType to shuffle all or part of the collection elements.
//
// Created by Khanh Le Do on 6/4/16.
// Copyright © 2016 kloc. All rights reserved.
//
import Foundation
/// Original shuffle methods given on Stackoverflow:
/// http://stackoverflow.com/questions/24026510/how-do-i-shuffle-an-array-in-swift
/// Here I added two more methods for special use cases:
/// - CollectionType.shuffleK
/// - MutableCollectionType.shuffleKInPlace
public extension MutableCollectionType where Index == Int {
/// Shuffle the elements of `self` in-place.
public mutating func shuffleInPlace() {
// empty and single-element collections don't shuffle
if count < 2 { return }
for i in 0..<count - 1 {
let j = Int(arc4random_uniform(UInt32(count - i))) + i
guard i != j else { continue }
swap(&self[i], &self[j])
}
}
/// Shuffle the first k elements of `self` in-place.
public mutating func shuffleKInPlace(k: Int) {
// empty and single-element collections don't shuffle
if count < 2 { return }
let finalCount = min(k, count)
for i in 0..<finalCount - 1 {
let j = Int(arc4random_uniform(UInt32(count - i))) + i
guard i != j else { continue }
swap(&self[i], &self[j])
}
}
}
public extension CollectionType {
/// Return a copy of `self` with its elements shuffled
public func shuffle() -> [Generator.Element] {
var list = Array(self)
list.shuffleInPlace()
return list
}
/// Return a subset (k-sized) of 'self' with elements shuffled from the original set
public func shuffleK(k: Int) -> [Generator.Element] {
var list = Array(self)
list.shuffleKInPlace(k)
let retSlice = list[0...(k-1)]
return Array(retSlice)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment