Dire che ho un array [1, 2, 3, 4, 5]
. Come posso iterare due alla volta?Iterate su collection two alla volta in Swift
Iteration 1: (1, 2)
Iteration 2: (3, 4)
Iteration 3: (5, nil)
Dire che ho un array [1, 2, 3, 4, 5]
. Come posso iterare due alla volta?Iterate su collection two alla volta in Swift
Iteration 1: (1, 2)
Iteration 2: (3, 4)
Iteration 3: (5, nil)
È possibile utilizzare un ciclo progressione chiamato passo (a :, da :) a iterare gli elementi ogni n elementi:
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"
Se l'array avrà un numero di elementi, si sarebbe in grado di scrivere qualcosa del genere:
for i in 0...arr.count/2 {
print(arr[2*...2*i+1])
Tuttavia questo non è sempre il caso. Inoltre, nil
non è sempre compatibile con il tipo di elementi nella matrice, come quello nell'esempio (nil
non è compatibile con Int
, solo con Int?
).
Un'altra soluzione potrebbe essere quella di estendere Array
e aggiungere un metodo pair()
, che restituisce una tupla (le tuple possono essere eterogenee). Puoi usare pair
per camminare all'interno di tutte le coppie dell'array, oppure puoi estendere ancora di più la struttura Array
e aggiungere pairs()
che restituisce una serie di tuple. Nota che dal momento che il secondo elemento della tupla è uno Optional
, dovrai scartarlo prima dell'uso.
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)
}
Un approccio sarebbe incapsulare l'array in una classe. I valori di ritorno per ottenere coppie di articoli sarebbero opzionali per la protezione da chiamate fuori intervallo.
Esempio:
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)
}
}
io personalmente non piace scorrendo la metà della lista (soprattutto a causa del dividendo), ecco come mi piace farlo:
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;
}
È scorrere l'array incrementando di 2.
Se si desidera avere nulla nell'elemento, è necessario utilizzare optionals.
Si dovrebbe' Si dichiara a let, in quanto il suo valore non cambia. – Cristik
Nota: il primo elemento della tupla non ha bisogno di essere un opzionale considerando il fatto che l'array di input ha solo interi (Int) e quindi non sarà mai nullo quindi puoi dichiararlo come [(Int, Int?) ] –
Fantastico! Che ne dici di qualcosa che non è indicizzabile da intero? – fumoboy007
@ fumoboy007 Non sapevo che si potesse avere un array non indicizzabile dal numero intero –