Powiedz, że mam tablicę [1, 2, 3, 4, 5]
. Jak mogę powtórzyć dwa naraz?Powtarzaj kolekcję po dwa naraz w Swift
Iteration 1: (1, 2)
Iteration 2: (3, 4)
Iteration 3: (5, nil)
Powiedz, że mam tablicę [1, 2, 3, 4, 5]
. Jak mogę powtórzyć dwa naraz?Powtarzaj kolekcję po dwa naraz w Swift
Iteration 1: (1, 2)
Iteration 2: (3, 4)
Iteration 3: (5, nil)
Można użyć pętli progresji nazwie kroku (do :, przez :) iteracyjne nad swoimi elementami co n elementy:
Xcode 8.3.2 • Swift 3.1
let array = Array(1...5)
let pairs = stride(from: 0, to: array.count, by: 2).map {
(array[$0], $0 < array.count-1 ? array[$0.advanced(by: 1)] : nil)
} // [(.0 1, {some 2}), (.0 3, {some 4}), (.0 5, nil)]
print(pairs) // "[(1, Optional(2)), (3, Optional(4)), (5, nil)]\n"
Jeśli tablica miałaby parzystą liczbę elementów, byłbyś w stanie napisać coś takiego:
for i in 0...arr.count/2 {
print(arr[2*...2*i+1])
jednak, że nie zawsze jest to przypadek. Co więcej, nil
nie zawsze jest kompatybilny z typem elementów w tablicy, podobnie jak w twoim przykładzie (nil
nie jest kompatybilny z Int
, tylko z Int?
).
Innym rozwiązaniem byłoby rozszerzenie Array
i dodanie metody pair()
, która zwraca krotkę (krotki mogą być heterogeniczne). Możesz użyć pair
, aby przejść przez wszystkie pary w tablicy, lub możesz rozszerzyć jeszcze bardziej strukturę i dodać pairs()
, która zwróci tablicę krotek. Zauważ, że skoro drugi element krotki to Optional
, musisz go rozwinąć przed użyciem.
extension Array {
func pair(i: Index) -> (Element, Element?) {
return (self[i], i < self.count - 1 ? self[i+1] : nil)
}
func pairs() -> [(Element, Element?)] {
var result = [(Element, Element?)]()
for i in 0...arr.count/2 {
result.append(self.pair(2*i))
}
return result
}
}
let arr = [1, 2, 3, 4, 5]
for i in 0...arr.count/2 {
print(arr.pair(2*i))
}
for pair in arr.pairs() {
print(pair)
}
Jednym podejściem byłoby hermetyzacja tablicy w klasie. Wartości zwracane dla uzyskania par elementów będą opcjami do ochrony przed połączeniami poza zasięgiem.
Przykład:
class Pairs {
let source = [1, 2, 3, 4, 5] // Or set with init()
var offset = 0
func nextpair() -> (Int?, Int?) {
var first: Int? = nil
var second: Int? = nil
if offset < source.count {
first = source[offset]
offset++
}
if offset < source.count {
second = source[offset]
offset++
}
return (first, second)
}
}
Ja osobiście lubię zapętlenie przez pół liście (głównie ze względu na podział), więc tutaj jest jak chciałbym to zrobić:
let array = [1,2,3,4,5];
var i = 0;
while i < array.count {
var a = array[i];
var b : Int? = nil;
if i + 1 < array.count {
b = array[i+1];
}
print("(\(a), \(b))");
i += 2;
}
You pętli za pośrednictwem tablicy przez zwiększanie o 2.
Jeśli chcesz mieć zero w elemencie, musisz użyć opcji.
Powinieneś” deklarujemy jako let, ponieważ jego wartość się nie zmienia. – Cristik
Uwaga: pierwszy element krotki nie musi być opcjonalny, biorąc pod uwagę fakt, że tablica wejściowa ma tylko liczby całkowite (Int) i dlatego nigdy nie będzie zerowa, więc możesz ją zadeklarować jako [(Int, Int?) ] –
Fajnie! Co powiesz na coś, co nie jest indeksowane przez integer? – fumoboy007
@ fumoboy007 Nie wiedziałem, że możesz mieć tablicę, która nie jest indeksowana przez liczbę całkowitą –