Antworten:
Ja. Ab Swift 3.0 können Sie die enumerated()
Methode verwenden , um über das Array zu iterieren , wenn Sie den Index für jedes Element zusammen mit seinem Wert benötigen . Es gibt eine Folge von Paaren zurück, die aus dem Index und dem Wert für jedes Element im Array bestehen. Zum Beispiel:
for (index, element) in list.enumerated() {
print("Item \(index): \(element)")
}
Vor Swift 3.0 und nach Swift 2.0 wurde die Funktion aufgerufen enumerate()
:
for (index, element) in list.enumerate() {
print("Item \(index): \(element)")
}
Vor Swift 2.0 enumerate
war eine globale Funktion.
for (index, element) in enumerate(list) {
println("Item \(index): \(element)")
}
enumerate
?
enumerating
für Swift 4 Aufregend!
for (index, element) in
bei der Verwendung enumerated
ist irreführend. sollte seinfor (offset, element) in
Swift 5 stellt ein Verfahren genannt enumerated()
für Array
. enumerated()
hat die folgende Erklärung:
func enumerated() -> EnumeratedSequence<Array<Element>>
Gibt eine Folge von Paaren (n, x) zurück, wobei n eine aufeinanderfolgende ganze Zahl ab Null darstellt und x ein Element der Folge darstellt.
In den einfachsten Fällen können Sie enumerated()
eine for-Schleife verwenden. Zum Beispiel:
let list = ["Car", "Bike", "Plane", "Boat"]
for (index, element) in list.enumerated() {
print(index, ":", element)
}
/*
prints:
0 : Car
1 : Bike
2 : Plane
3 : Boat
*/
Beachten Sie jedoch, dass Sie nicht auf die Verwendung enumerated()
mit einer for-Schleife beschränkt sind. Wenn Sie vorhaben, enumerated()
eine for-Schleife für etwas zu verwenden, das dem folgenden Code ähnelt, machen Sie es falsch:
let list = [Int](1...5)
var arrayOfTuples = [(Int, Int)]()
for (index, element) in list.enumerated() {
arrayOfTuples += [(index, element)]
}
print(arrayOfTuples) // prints [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
Ein schnellerer Weg, dies zu tun, ist:
let list = [Int](1...5)
let arrayOfTuples = Array(list.enumerated())
print(arrayOfTuples) // prints [(offset: 0, element: 1), (offset: 1, element: 2), (offset: 2, element: 3), (offset: 3, element: 4), (offset: 4, element: 5)]
Alternativ können Sie auch verwenden enumerated()
mit map
:
let list = [Int](1...5)
let arrayOfDictionaries = list.enumerated().map { (a, b) in return [a : b] }
print(arrayOfDictionaries) // prints [[0: 1], [1: 2], [2: 3], [3: 4], [4: 5]]
Darüber hinaus hat es zwar einige Einschränkungen , forEach
kann es außerdem ein guter Ersatz für eine for-Schleife sein:
let list = [Int](1...5)
list.reversed().enumerated().forEach { print($0, ":", $1) }
/*
prints:
0 : 5
1 : 4
2 : 3
3 : 2
4 : 1
*/
Mit enumerated()
und makeIterator()
können Sie sogar manuell auf Ihrem Computer iterieren Array
. Zum Beispiel:
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
var generator = ["Car", "Bike", "Plane", "Boat"].enumerated().makeIterator()
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: .system)
button.setTitle("Tap", for: .normal)
button.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
button.addTarget(self, action: #selector(iterate(_:)), for: .touchUpInside)
view.addSubview(button)
}
@objc func iterate(_ sender: UIButton) {
let tuple = generator.next()
print(String(describing: tuple))
}
}
PlaygroundPage.current.liveView = ViewController()
/*
Optional((offset: 0, element: "Car"))
Optional((offset: 1, element: "Bike"))
Optional((offset: 2, element: "Plane"))
Optional((offset: 3, element: "Boat"))
nil
nil
nil
*/
enumerate
?
Ich habe diese Antwort gefunden, als ich nach einer Möglichkeit gesucht habe, dies mit einem Wörterbuch zu tun , und es stellt sich heraus, dass es ziemlich einfach ist, sie anzupassen. Übergeben Sie einfach ein Tupel für das Element.
// Swift 2
var list = ["a": 1, "b": 2]
for (index, (letter, value)) in list.enumerate() {
print("Item \(index): \(letter) \(value)")
}
Sie können einfach eine Aufzählungsschleife verwenden, um das gewünschte Ergebnis zu erzielen:
Swift 2:
for (index, element) in elements.enumerate() {
print("\(index): \(element)")
}
Swift 3 & 4:
for (index, element) in elements.enumerated() {
print("\(index): \(element)")
}
Oder Sie können einfach eine for-Schleife durchlaufen, um das gleiche Ergebnis zu erhalten:
for index in 0..<elements.count {
let element = elements[index]
print("\(index): \(element)")
}
Ich hoffe es hilft.
for (index, element) in arrayOfValues.enumerate() {
// do something useful
}
oder mit Swift 3 ...
for (index, element) in arrayOfValues.enumerated() {
// do something useful
}
Am häufigsten verwende ich jedoch Aufzählung in Kombination mit Karte oder Filter. Zum Beispiel mit der Bearbeitung einiger Arrays.
In diesem Array wollte ich ungerade oder gerade indizierte Elemente filtern und sie von Ints in Doubles konvertieren. So enumerate()
bekommt man Index und das Element, dann Filter prüfen der Index, und schließlich den resultierenden Tupel ich es nur das Element Karte loszuwerden.
let evens = arrayOfValues.enumerate().filter({
(index: Int, element: Int) -> Bool in
return index % 2 == 0
}).map({ (_: Int, element: Int) -> Double in
return Double(element)
})
let odds = arrayOfValues.enumerate().filter({
(index: Int, element: Int) -> Bool in
return index % 2 != 0
}).map({ (_: Int, element: Int) -> Double in
return Double(element)
})
Verwenden von .enumerate()
Werken, liefert jedoch nicht den wahren Index des Elements. Es wird nur ein Int bereitgestellt, das mit 0 beginnt und für jedes aufeinanderfolgende Element um 1 erhöht wird. Dies ist normalerweise irrelevant, aber es besteht die Möglichkeit eines unerwarteten Verhaltens, wenn es mit dem ArraySlice
Typ verwendet wird. Nehmen Sie den folgenden Code:
let a = ["a", "b", "c", "d", "e"]
a.indices //=> 0..<5
let aSlice = a[1..<4] //=> ArraySlice with ["b", "c", "d"]
aSlice.indices //=> 1..<4
var test = [Int: String]()
for (index, element) in aSlice.enumerate() {
test[index] = element
}
test //=> [0: "b", 1: "c", 2: "d"] // indices presented as 0..<3, but they are actually 1..<4
test[0] == aSlice[0] // ERROR: out of bounds
Es ist ein etwas erfundenes Beispiel, und es ist in der Praxis kein alltägliches Problem, aber ich denke, es lohnt sich zu wissen, dass dies passieren kann.
it does not actually provide the true index of the element; it only provides an Int beginning with 0 and incrementing by 1 for each successive element
Ja, deshalb heißt es Aufzählung . Außerdem ist Slice kein Array, daher ist es keine Überraschung, dass es sich anders verhält. Hier gibt es keinen Fehler - alles ist beabsichtigt. :)
filter
zuerst verwenden?
Der Vollständigkeit halber können Sie einfach Ihre Array-Indizes durchlaufen und mithilfe des Index auf das Element am entsprechenden Index zugreifen:
let list = [100,200,300,400,500]
for index in list.indices {
print("Element at:", index, " Value:", list[index])
}
ForEach verwenden
list.indices.forEach {
print("Element at:", $0, " Value:", list[$0])
}
Sammlungsmethode enumerated()
verwenden. Beachten Sie, dass eine Sammlung von Tupeln mit offset
und zurückgegeben wird element
:
for item in list.enumerated() {
print("Element at:", item.offset, " Value:", item.element)
}
mit forEach:
list.enumerated().forEach {
print("Element at:", $0.offset, " Value:", $0.element)
}
Diese werden gedruckt
Element bei: 0 Wert: 100
Element bei: 1 Wert: 200
Element bei: 2 Wert: 300
Element bei: 3 Wert: 400
Element bei: 4 Wert: 500
Wenn Sie den Array-Index (nicht den Offset) und sein Element benötigen, können Sie Collection erweitern und eine eigene Methode erstellen, um die indizierten Elemente abzurufen:
extension Collection {
func indexedElements(body: ((index: Index, element: Element)) throws -> Void) rethrows {
var index = startIndex
for element in self {
try body((index,element))
formIndex(after: &index)
}
}
}
Eine andere mögliche Implementierung, wie von Alex vorgeschlagen, besteht darin, die Sammlungsindizes mit ihren Elementen zu komprimieren:
extension Collection {
func indexedElements(body: ((index: Index, element: Element)) throws -> Void) rethrows {
for element in zip(indices, self) { try body(element) }
}
}
Testen:
let list = ["100","200","300","400","500"]
list.dropFirst(2).indexedElements {
print("Index:", $0.index, "Element:", $0.element)
}
Dies wird gedruckt
Index: 2 Element: 300
Index: 3 Element: 400
Index: 4 Element: 500
enumeratedIndices
indem Sie mitzip(self.indices, self)
for element in zip(indices, self) { try body(element) }
. Übrigens mag ich die von mir indexedElements
for
Schleife funktioniert, aber auchzip(self.indices, self) .forEach(body)
forEach
macht eine for-Schleife hinter den Kulissen. Ich ziehe es vor, es einfach zu halten github.com/apple/swift/blob/master/stdlib/public/core/… @inlinable public func forEach( _ body: (Element) throws -> Void ) rethrows { for element in self { try body(element) } } }
Xcode 8 und Swift 3: Array können mit aufgelistet werden tempArray.enumerated()
Beispiel:
var someStrs = [String]()
someStrs.append("Apple")
someStrs.append("Amazon")
someStrs += ["Google"]
for (index, item) in someStrs.enumerated()
{
print("Value at index = \(index) is \(item)").
}
Konsole:
Value at index = 0 is Apple
Value at index = 1 is Amazon
Value at index = 2 is Google
Für diejenigen, die verwenden möchten forEach
.
Swift 4
extension Array {
func forEachWithIndex(_ body: (Int, Element) throws -> Void) rethrows {
try zip((startIndex ..< endIndex), self).forEach(body)
}
}
Oder
array.enumerated().forEach { ... }
Für das, was Sie tun möchten, sollten Sie die enumerated()
Methode auf Ihrem Array verwenden :
for (index, element) in list.enumerated() {
print("\(index) - \(element)")
}
Wir haben die Aufzählungsfunktion aufgerufen, um dies zu implementieren. mögen
für (Index, Element) in array.enumerate () {
// Index ist die Indexposition des Arrays
// Element ist Element des Arrays
}}