咱們想經過 Swift 簡單的實現全排列。html
首先先寫個例子,列出全部把元素插入到數組中的狀況:git
func between<T>(x: T, ys: [T]) -> [[T]] { if let (head, tail) = ys.decompose { return [[x] + ys] + between(x, tail).map { [head] + $0 } } else { return [[x]] } } between(0, [1, 2, 3]) // [[0, 1, 2, 3], [1, 0, 2, 3], [1, 2, 0, 3], [1, 2, 3, 0]]
接下來再經過 between
函數實現全排列:github
func permutations<T>(xs: [T]) -> [[T]] { if let (head, tail) = xs.decompose { return permutations(tail) >>= { permTail in between(head, permTail) } } else { return [[]] } }
其中 >>=
這個符號前面有提到過,返回全部的組合結果。完整的實現代碼以下:數組
extension Array { var decompose : (head: T, tail: [T])? { return (count > 0) ? (self[0], Array(self[1..<count])) : nil } } infix operator >>= {} func >>=<A, B>(xs: [A], f: A -> [B]) -> [B] { return xs.map(f).reduce([], combine: +) } func between<T>(x: T, ys: [T]) -> [[T]] { if let (head, tail) = ys.decompose { return [[x] + ys] + between(x, tail).map { [head] + $0 } } else { return [[x]] } } func permutations<T>(xs: [T]) -> [[T]] { if let (head, tail) = xs.decompose { return permutations(tail) >>= { permTail in between(head, permTail) } } else { return [[]] } }
咱們能夠在原來的API上面封裝一層減小頻繁解包的麻煩:app
typealias JSONDictionary = [String:AnyObject] func decodeJSON(data: NSData) -> JSONDictionary? { return NSJSONSerialization.JSONObjectWithData(data, options: .allZeros, error: nil) as? JSONDictionary }
固然 encode
也同樣:函數
func encodeJSON(input: JSONDictionary) -> NSData? { return NSJSONSerialization.dataWithJSONObject(input, options: .allZeros, error: nil) }