值的範圍是ForwardIndexType
,所以你只能他們advance()
, 或計算distance()
,但是沒有定義減法-
。提前金額必須是相應的 類型T.Distance
。因此,這將是一個可能的實現:
extension Range {
func splitEvery(nInEach: T.Distance) -> [Range] {
var result = [Range]() // Start with empty array
var from = self.startIndex
while from != self.endIndex {
// Advance position, but not beyond the end index:
let to = advance(from, nInEach, self.endIndex)
result.append(from ..< to)
// Continue with next interval:
from = to
}
return result
}
}
例:然而
println((0 ..< 10).splitEvery(3))
// Output: [0..<3, 3..<6, 6..<9, 9..<10]
注意0 ..< 10
不是整數的列表(或陣列)。要分割陣列成子陣列可以定義一個類似的延伸:
extension Array {
func splitEvery(nInEach: Int) -> [[T]] {
var result = [[T]]()
for from in stride(from: 0, to: self.count, by: nInEach) {
let to = advance(from, nInEach, self.count)
result.append(Array(self[from ..< to]))
}
return result
}
}
實施例:
println([1, 1, 2, 3, 5, 8, 13].splitEvery(3))
// Output: [[1, 1, 2], [3, 5, 8], [13]]
更一般的方法可以是分割所有可切片對象。但是Sliceable
是協議和協議不能被擴展。你可以做什麼,而不是是 定義功能,是以可切片的對象作爲第一個參數:
func splitEvery<S : Sliceable>(seq : S, nInEach : S.Index.Distance) -> [S.SubSlice] {
var result : [S.SubSlice] = []
var from = seq.startIndex
while from != seq.endIndex {
let to = advance(from, nInEach, seq.endIndex)
result.append(seq[from ..< to])
from = to
}
return result
}
(請注意,這功能是完全無關的(擴展)方法 定義上文)
例:
println(splitEvery("abcdefg", 2))
// Output: [ab, cd, ef, g]
println(splitEvery([3.1, 4.1, 5.9, 2.6, 5.3], 2))
// Output: [[3.1, 4.1], [5.9, 2.6], [5.3]]
範圍一再沒有可切片,但你可以定義一個單獨的函數,它接受一個 範圍的說法:
func splitEvery<T>(range : Range<T>, nInEach : T.Distance) -> [Range<T>] {
var result : [Range<T>] = []
var from = range.startIndex
while from != range.endIndex {
let to = advance(from, nInEach, range.endIndex)
result.append(from ..< to)
from = to
}
return result
}
例子:
println(splitEvery(0 ..< 10, 3))
// Output: [0..<3, 3..<6, 6..<9, 9..<10]
太棒了 - 一個通用的實現! – kfmfe04 2014-11-01 19:21:22
奇怪的是,這在Playground中完美地工作,但我有問題讓它在一個項目中編譯 - 我在這裏發佈了一個新條目:http://stackoverflow.com/q/26694296/975129 – kfmfe04 2014-11-01 23:20:35
@ kfmfe04:我有稍微擴大了答案。如果您需要更多信息,請與我們聯繫。 – 2014-11-02 09:58:27