Created
April 16, 2016 09:38
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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