2015-01-16 4 views
1

Есть ли что-то похожее на Ruby's Enumerable # each_slice в Swift?Быстрый эквивалент each_slice

Рубин пример:

arr = ["a", "b", "c", "d"] 
arr.each_slice(2) {|s1, s2| puts s1 + s2 } 

Выход:

ab 
cd 
+0

Я думаю, ответ прост: нет. Вам нужно извлечь значения с помощью обычного цикла и создать диапазоны. –

ответ

5

В небольшой модификации кода из How to implement Haskell's splitEvery in Swift?, можно определить расширение массива

extension Array { 
    func eachSlice<S>(nInEach: Int, transform: [T] -> S) -> [S] { 
     var result = [S]() 
     for from in stride(from: 0, to: self.count, by: nInEach) { 
      let to = advance(from, nInEach, self.count) 
      result.append(transform(Array(self[from ..< to]))) 
     } 
     return result 
    } 
} 

, а затем использовать его в качестве

let arr = ["a", "b", "c", "d"] 
arr.eachSlice(2) { println("".join($0)) } 

Выход:

 
ab 
cd 

Другой пример :

let iarr = [1, 2, 3, 4, 5, 6, 7] 
let sliceSums = iarr.eachSlice(3) { 
    reduce($0, 0) { $0 + $1 } // sum of slice elements 
} 
println(sliceSums) 
// [6, 15, 7] 

Обновление для Swift 3:

extension Array { 
    func eachSlice<S>(_ nInEach: Int, transform: (ArraySlice<Element>) -> S) -> [S] { 
     var result = [S]() 
     var from = startIndex 
     while from != endIndex { 
      let to = indices.index(from, offsetBy: nInEach, limitedBy: endIndex) ?? endIndex 
      result.append(transform(self[from ..< to])) 
      from = to 
     } 
     return result 
    } 
} 

let iarr = [1, 2, 3, 4, 5, 6, 7] 
let sliceSums = iarr.eachSlice(3) { $0.reduce(0, +) } 
print(sliceSums) // [6, 15, 7] 
+0

Ничего себе, просто ничего себе. @Jonas, вы должны отметить это как принято. – x4h1d

1

Чтобы изменить свой комментарий:

let a = ["a", "b", "c", "d"] 
for var i = 0; i < a.count; i+=2 { 
    let a1 = a[i] 
    let a2 = a[i+1] 
    println("\(a1)\(a2)") 
} 

Обратите внимание, что это не проверяет неравномерного подсчета элементов.

Смежные вопросы