Szukaj…


Wprowadzenie

Tablica jest uporządkowanym typem kolekcji o swobodnym dostępie. Tablice są jednym z najczęściej używanych typów danych w aplikacji. Używamy typu Array do przechowywania elementów jednego typu, typu Element tablicy. Tablica może przechowywać dowolne elementy --- od liczb całkowitych przez ciągi znaków po klasy.

Składnia

  • Array <Element> // Typ tablicy z elementami typu Element
  • [Element] // Cukier syntaktyczny dla typu tablicy z elementami typu Element
  • [element0, element1, element2, ... elementN] // Literał tablicowy
  • [Element] () // Tworzy nową pustą tablicę typu [Element]
  • Array (count: repeatValue :) // Tworzy tablicę elementów count , z których każdy jest inicjowany na repeatedValue
  • Array (_ :) // Tworzy tablicę z dowolnej sekwencji

Uwagi

Tablice są uporządkowanym zbiorem wartości. Wartości mogą się powtarzać, ale muszą być tego samego typu.

Semantyka wartości

Kopiowanie tablicy spowoduje skopiowanie wszystkich elementów z oryginalnej tablicy.

Zmiana nowej tablicy nie zmieni oryginalnej tablicy.

var originalArray = ["Swift", "is", "great!"]
var newArray = originalArray
newArray[2] = "awesome!"
//originalArray = ["Swift", "is", "great!"]
//newArray = ["Swift", "is", "awesome!"]

Skopiowane tablice będą dzielić to samo miejsce w pamięci co oryginał, dopóki nie zostaną zmienione. W wyniku tego występuje obniżenie wydajności, gdy skopiowana tablica otrzymuje własne miejsce w pamięci, gdy jest zmieniana po raz pierwszy.

Podstawy tablic

Array to uporządkowany typ kolekcji w standardowej bibliotece Swift. Zapewnia losowy dostęp O (1) i dynamiczną realokację. Tablica jest typem ogólnym , więc typ zawartych w niej wartości jest znany w czasie kompilacji.

Ponieważ Array jest typem wartości , jej zmienność jest definiowana przez to, czy jest opisana jako var ( var ) czy let (niezmienna).

Typ [Int] (co oznacza: tablica zawierająca Int s) to cukier składniowy dla Array<T> .

Przeczytaj więcej o tablicach w Swift Programming Language .

Puste tablice

Następujące trzy deklaracje są równoważne:

// A mutable array of Strings, initially empty.

var arrayOfStrings: [String] = []      // type annotation + array literal
var arrayOfStrings = [String]()        // invoking the [String] initializer
var arrayOfStrings = Array<String>()   // without syntactic sugar

Tablice literałów

Literał tablicowy zapisywany jest za pomocą nawiasów kwadratowych otaczających elementy oddzielone przecinkami:

// Create an immutable array of type [Int] containing 2, 4, and 7
let arrayOfInts = [2, 4, 7]

Kompilator zwykle może wnioskować o typie tablicy na podstawie elementów literału, ale wyraźne adnotacje typu mogą zastąpić domyślną:

let arrayOfUInt8s: [UInt8] = [2, 4, 7]   // type annotation on the variable
let arrayOfUInt8s = [2, 4, 7] as [UInt8] // type annotation on the initializer expression
let arrayOfUInt8s = [2 as UInt8, 4, 7]   // explicit for one element, inferred for the others

Tablice z powtarzanymi wartościami

// An immutable array of type [String], containing ["Example", "Example", "Example"]
let arrayOfStrings = Array(repeating: "Example",count: 3)

Tworzenie tablic z innych sekwencji

let dictionary = ["foo" : 4, "bar" : 6]

// An immutable array of type [(String, Int)], containing [("bar", 6), ("foo", 4)]
let arrayOfKeyValuePairs = Array(dictionary)

Tablice wielowymiarowe

W Swift macierz wielowymiarowa jest tworzona przez zagnieżdżanie tablic: dwuwymiarowa tablica Int to [[Int]] (lub Array<Array<Int>> ).

let array2x3 = [
    [1, 2, 3],
    [4, 5, 6]
]
// array2x3[0][1] is 2, and array2x3[1][2] is 6.

Aby utworzyć wielowymiarową tablicę powtarzanych wartości, użyj zagnieżdżonych wywołań inicjalizatora tablicy:

var array3x4x5 = Array(repeating: Array(repeating: Array(repeating: 0,count: 5),count: 4),count: 3)

Dostęp do wartości macierzy

Poniższe przykłady wykorzystają tę tablicę do zademonstrowania dostępu do wartości

var exampleArray:[Int] = [1,2,3,4,5]
//exampleArray = [1, 2, 3, 4, 5]

Aby uzyskać dostęp do wartości o znanym indeksie, użyj następującej składni:

let exampleOne = exampleArray[2]
//exampleOne = 3

Uwaga: Wartość w indeksie drugim jest trzecią wartością w Array . Array używają indeksu zerowego, co oznacza, że pierwszy element w Array ma indeks 0.

let value0 = exampleArray[0]
let value1 = exampleArray[1]
let value2 = exampleArray[2]
let value3 = exampleArray[3]
let value4 = exampleArray[4]
//value0 = 1
//value1 = 2 
//value2 = 3
//value3 = 4
//value4 = 5

Uzyskaj dostęp do podzbioru Array za pomocą filtra:

var filteredArray = exampleArray.filter({ $0 < 4 })
//filteredArray = [1, 2, 3]

Filtry mogą mieć złożone warunki, takie jak filtrowanie tylko liczb parzystych:

var evenArray = exampleArray.filter({ $0 % 2 == 0 })
//evenArray = [2, 4]

Można również zwrócić indeks danej wartości, zwracając nil jeśli wartość nie została znaleziona.

exampleArray.indexOf(3) // Optional(2)

Istnieją metody dla pierwszej, ostatniej, maksymalnej lub minimalnej wartości w Array . Te metody zwrócą nil jeśli Array jest pusta.

exampleArray.first // Optional(1)
exampleArray.last // Optional(5)
exampleArray.maxElement() // Optional(5)
exampleArray.minElement() // Optional(1)

Przydatne metody

Określ, czy tablica jest pusta, czy zwróć jej rozmiar

var exampleArray = [1,2,3,4,5]
exampleArray.isEmpty //false
exampleArray.count //5

Odwróć tablicę Uwaga: Wynik nie jest wykonywany w tablicy, w której wywoływana jest metoda, i musi zostać umieszczony we własnej zmiennej.

exampleArray = exampleArray.reverse()
//exampleArray = [9, 8, 7, 6, 5, 3, 2]

Modyfikowanie wartości w tablicy

Istnieje wiele sposobów dodawania wartości do tablicy

var exampleArray = [1,2,3,4,5]
exampleArray.append(6)
//exampleArray = [1, 2, 3, 4, 5, 6]
var sixOnwards = [7,8,9,10]
exampleArray += sixOnwards
//exampleArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

i usuń wartości z tablicy

exampleArray.removeAtIndex(3)
//exampleArray = [1, 2, 3, 5, 6, 7, 8, 9, 10]
exampleArray.removeLast()
//exampleArray = [1, 2, 3, 5, 6, 7, 8, 9]
exampleArray.removeFirst()
//exampleArray = [2, 3, 5, 6, 7, 8, 9]

Sortowanie tablicy

var array = [3, 2, 1]

Tworzenie nowej posortowanej tablicy

Ponieważ Array jest zgodny z SequenceType , możemy wygenerować nową tablicę posortowanych elementów za pomocą wbudowanej metody sortowania.

2.1 2.2

W Swift 2 odbywa się to za pomocą metody sort() .

let sorted = array.sort()  // [1, 2, 3]
3.0

Począwszy od Swift 3, zmieniono jego nazwę na sorted() .

let sorted = array.sorted()  // [1, 2, 3]

Sortowanie istniejącej tablicy na miejscu

Ponieważ Array jest zgodny z MutableCollectionType , możemy sortować jego elementy na miejscu.

2.1 2.2

W Swift 2 odbywa się to za pomocą metody sortInPlace() .

array.sortInPlace() // [1, 2, 3]
3.0

Od Swift 3 zmieniono jego nazwę na sort() .

array.sort() // [1, 2, 3]

Uwaga: Aby skorzystać z powyższych metod, elementy muszą być zgodne z protokołem Comparable .

Sortowanie tablicy za pomocą niestandardowego porządku

Możesz także posortować tablicę za pomocą zamknięcia, aby określić, czy jeden element powinien być uporządkowany przed drugim - co nie jest ograniczone do tablic, w których elementy muszą być Comparable . Na przykład punkt Landmark nie ma sensu Comparable - ale nadal możesz sortować tablicę punktów orientacyjnych według wysokości lub nazwy.

struct Landmark {
    let name : String
    let metersTall : Int
}

var landmarks = [Landmark(name: "Empire State Building", metersTall: 443),
                 Landmark(name: "Eifell Tower", metersTall: 300),
                 Landmark(name: "The Shard", metersTall: 310)]
2.1 2.2
// sort landmarks by height (ascending)
landmarks.sortInPlace {$0.metersTall < $1.metersTall}

print(landmarks) // [Landmark(name: "Eifell Tower", metersTall: 300), Landmark(name: "The Shard", metersTall: 310), Landmark(name: "Empire State Building", metersTall: 443)]

// create new array of landmarks sorted by name
let alphabeticalLandmarks = landmarks.sort {$0.name < $1.name}

print(alphabeticalLandmarks) // [Landmark(name: "Eifell Tower", metersTall: 300), Landmark(name: "Empire State Building", metersTall: 443), Landmark(name: "The Shard", metersTall: 310)]
3.0
// sort landmarks by height (ascending)
landmarks.sort {$0.metersTall < $1.metersTall}

// create new array of landmarks sorted by name
let alphabeticalLandmarks = landmarks.sorted {$0.name < $1.name}

Uwaga: Porównanie ciągów może dać nieoczekiwane wyniki, jeśli ciągi są niespójne, patrz Sortowanie tablicy ciągów .

Przekształcanie elementów tablicy za pomocą mapy (_ :)

Ponieważ Array jest zgodny z SequenceType , możemy użyć map(_:) aby przekształcić tablicę A w tablicę B za pomocą zwrócenia typu (A) throws -> B

Na przykład, możemy go użyć do przekształcenia tablicy Int w tablicę String s, tak jak to:

let numbers = [1, 2, 3, 4, 5]
let words = numbers.map { String($0) }
print(words) // ["1", "2", "3", "4", "5"]

map(_:) wykona iterację w tablicy, stosując dane zamknięcie do każdego elementu. Wynik tego zamknięcia zostanie wykorzystany do zapełnienia nowej tablicy transformowanymi elementami.

Ponieważ String ma inicjalizator, który otrzymuje Int , możemy również użyć tej jaśniejszej składni:

let words = numbers.map(String.init)

Transformacja map(_:) nie musi zmieniać typu tablicy - na przykład można jej również użyć do pomnożenia tablicy Int przez dwa:

let numbers = [1, 2, 3, 4, 5]
let numbersTimes2 = numbers.map {$0 * 2}
print(numbersTimes2) // [2, 4, 6, 8, 10]

Wyodrębnianie wartości danego typu z tablicy za pomocą flatMap (_ :)

Tablica things zawiera wartości Any typu.

let things: [Any] = [1, "Hello", 2, true, false, "World", 3]

Możemy wyodrębnić wartości danego typu i utworzyć nową tablicę tego konkretnego typu. Powiedzmy, że chcemy wyodrębnić wszystkie Int(s) i umieścić je w Int Array w bezpieczny sposób.

let numbers = things.flatMap { $0 as? Int }

Teraz numbers są zdefiniowane jako [Int] . Funkcja flatMap odrzuca wszystkie elementy nil dlatego wynik zawiera tylko następujące wartości:

[1, 2, 3]

Filtrowanie tablicy

Możesz użyć metody filter(_:) na SequenceType , aby utworzyć nową tablicę zawierającą elementy sekwencji, które spełniają dany predykat, który można podać jako zakończenie .

Na przykład, filtrowanie liczb parzystych z [Int] :

let numbers = [22, 41, 23, 30]

let evenNumbers = numbers.filter { $0 % 2 == 0 }

print(evenNumbers)  // [22, 30]

Filtrowanie [Person] , gdy jego wiek jest mniejszy niż 30:

struct Person {
    var age : Int
}

let people = [Person(age: 22), Person(age: 41), Person(age: 23), Person(age: 30)]

let peopleYoungerThan30 = people.filter { $0.age < 30 }

print(peopleYoungerThan30) // [Person(age: 22), Person(age: 23)]

Filtrowanie zera z transformacji Array za pomocą flatMap (_ :)

Możesz użyć flatMap(_:) w podobny sposób jak map(_:) w celu utworzenia tablicy poprzez zastosowanie transformacji do elementów sekwencji.

extension SequenceType {
    public func flatMap<T>(@noescape transform: (Self.Generator.Element) throws -> T?) rethrows -> [T]
}

Różnica w stosunku do tej wersji flatMap(_:) polega na tym, że oczekuje ona, że zamknięcie transformacji zwróci wartość opcjonalną T? dla każdego z elementów. Następnie bezpiecznie rozpakuje każdą z tych opcjonalnych wartości, odfiltrowując nil - co da tablicę [T] .

Na przykład, może to w celu przekształcenia [String] w [Int] używając Int failable „s String inicjator , filtrowanie żadnych elementów, które nie mogą być zamienione:

let strings = ["1", "foo", "3", "4", "bar", "6"]

let numbersThatCanBeConverted = strings.flatMap { Int($0) }

print(numbersThatCanBeConverted) // [1, 3, 4, 6]

Możesz także użyć funkcji flatMap(_:) do odfiltrowania wartości nil , aby po prostu przekonwertować tablicę opcji na tablicę nie-opcji:

let optionalNumbers : [Int?] = [nil, 1, nil, 2, nil, 3]

let numbers = optionalNumbers.flatMap { $0 }

print(numbers) // [1, 2, 3]

Subskrybowanie tablicy za pomocą zakresu

Można wyciągnąć szereg kolejnych elementów z tablicy za pomocą zakresu.

let words = ["Hey", "Hello", "Bonjour", "Welcome", "Hi", "Hola"]
let range = 2...4
let slice = words[range] // ["Bonjour", "Welcome", "Hi"]

Subskrybowanie tablicy za pomocą zakresu zwraca ArraySlice . To podsekwencja macierzy.

W naszym przykładzie mamy Array of Strings, więc ArraySlice<String> .

Chociaż ArraySlice jest zgodny z CollectionType i może być używany z sort , filter itp., Jego celem nie jest przechowywanie długoterminowe, ale obliczenia przejściowe: należy go przekonwertować z powrotem na macierz, jak tylko skończysz z nim pracować.

W tym celu użyj inicjatora Array() :

let result = Array(slice)

Podsumowując w prostym przykładzie bez pośrednich kroków:

let words = ["Hey", "Hello", "Bonjour", "Welcome", "Hi", "Hola"]
let selectedWords = Array(words[2...4]) // ["Bonjour", "Welcome", "Hi"]

Grupowanie wartości tablic

Jeśli mamy taką strukturę

struct Box {
    let name: String
    let thingsInside: Int
}

oraz tablicę Box(es)

let boxes = [
    Box(name: "Box 0", thingsInside: 1),
    Box(name: "Box 1", thingsInside: 2),
    Box(name: "Box 2", thingsInside: 3),
    Box(name: "Box 3", thingsInside: 1),
    Box(name: "Box 4", thingsInside: 2),
    Box(name: "Box 5", thingsInside: 3),
    Box(name: "Box 6", thingsInside: 1)
]

możemy pogrupować pola według właściwości thingsInside , aby uzyskać Dictionary którym key jest liczba rzeczy, a wartością jest tablica pól.

let grouped = boxes.reduce([Int:[Box]]()) { (res, box) -> [Int:[Box]] in
    var res = res
    res[box.thingsInside] = (res[box.thingsInside] ?? []) + [box]
    return res
}

Teraz zgrupowane jest [Int:[Box]] i ma następującą treść

[
    2: [Box(name: "Box 1", thingsInside: 2), Box(name: "Box 4", thingsInside: 2)], 
    3: [Box(name: "Box 2", thingsInside: 3), Box(name: "Box 5", thingsInside: 3)],
    1: [Box(name: "Box 0", thingsInside: 1), Box(name: "Box 3", thingsInside: 1), Box(name: "Box 6", thingsInside: 1)]
]

Spłaszczanie wyniku transformacji Array za pomocą flatMap (_ :)

Oprócz możliwości utworzenia tablicy przez odfiltrowanie nil z transformowanych elementów sekwencji, istnieje również wersja flatMap(_:) która oczekuje, że zamknięcie transformacji zwróci sekwencję S

extension SequenceType {
    public func flatMap<S : SequenceType>(transform: (Self.Generator.Element) throws -> S) rethrows -> [S.Generator.Element]
}

Każda sekwencja z transformacji zostanie połączona, w wyniku czego powstanie tablica zawierająca połączone elementy każdej sekwencji - [S.Generator.Element] .

Łączenie znaków w tablicę ciągów

Na przykład możemy go użyć do pobrania tablicy ciągów pierwszych i połączenia ich znaków w jedną tablicę:

let primes = ["2", "3", "5", "7", "11", "13", "17", "19"]
let allCharacters = primes.flatMap { $0.characters }
// => "["2", "3", "5", "7", "1", "1", "1", "3", "1", "7", "1", "9"]"

Podział powyższego przykładu:

  1. primes to [String] (Ponieważ tablica jest sekwencją, możemy wywołać na niej flatMap(_:) ).
  2. Zamknięcie transformacji przyjmuje jeden z elementów primes , String ( Array<String>.Generator.Element ).
  3. Zamknięcie następnie zwraca sekwencję typu String.CharacterView .
  4. Wynikiem jest tablica zawierająca połączone elementy wszystkich sekwencji z każdego wywołania zamknięcia transformacji - [String.CharacterView.Generator.Element] .

Spłaszczanie tablicy wielowymiarowej

Ponieważ flatMap(_:) połączy sekwencje zwrócone z wywołań transformacji, można go użyć do spłaszczenia tablicy wielowymiarowej - takiej jak tablica 2D w tablicę 1D, tablica 3D w tablicę 2D itp.

Można to zrobić po prostu zwracając podany element $0 (tablica zagnieżdżona) w zamknięciu:

// A 2D array of type [[Int]]
let array2D = [[1, 3], [4], [6, 8, 10], [11]]

// A 1D array of type [Int]
let flattenedArray = array2D.flatMap { $0 }

print(flattenedArray) // [1, 3, 4, 6, 8, 10, 11]

Sortowanie tablicy ciągów

3.0

Najprostszym sposobem jest użycie sorted() :

let words = ["Hello", "Bonjour", "Salute", "Ahola"]
let sortedWords = words.sorted()
print(sortedWords) // ["Ahola", "Bonjour", "Hello", "Salute"]

lub sort()

var mutableWords = ["Hello", "Bonjour", "Salute", "Ahola"]
mutableWords.sort()
print(mutableWords) // ["Ahola", "Bonjour", "Hello", "Salute"]

Możesz przekazać zamknięcie jako argument do sortowania:

let words = ["Hello", "Bonjour", "Salute", "Ahola"]
let sortedWords = words.sorted(isOrderedBefore: { $0 > $1 })
print(sortedWords) // ["Salute", "Hello", "Bonjour", "Ahola"]

Alternatywna składnia z końcowym zamknięciem:

let words = ["Hello", "Bonjour", "Salute", "Ahola"]
let sortedWords = words.sorted() { $0 > $1 }
print(sortedWords) // ["Salute", "Hello", "Bonjour", "Ahola"]

Ale pojawią się nieoczekiwane wyniki, jeśli elementy w tablicy nie będą spójne:

let words = ["Hello", "bonjour", "Salute", "ahola"]
let unexpected = words.sorted()
print(unexpected) // ["Hello", "Salute", "ahola", "bonjour"]

Aby rozwiązać ten problem, albo posortuj małe wersje elementów:

let words = ["Hello", "bonjour", "Salute", "ahola"]
let sortedWords = words.sorted { $0.lowercased() < $1.lowercased() }
print(sortedWords) // ["ahola", "bonjour", "Hello", "Salute"]

Lub import Foundation i użyj metod porównania NSString, takich jak caseInsensitiveCompare :

let words = ["Hello", "bonjour", "Salute", "ahola"]
let sortedWords = words.sorted { $0.caseInsensitiveCompare($1) == .orderedAscending }
print(sortedWords) // ["ahola", "bonjour", "Hello", "Salute"]

Alternatywnie, użyj localizedCaseInsensitiveCompare , który może zarządzać znakami diakrytycznymi.

Aby poprawnie posortować ciągi według wartości liczbowej, którą zawierają, użyj compare z opcją .numeric :

let files = ["File-42.txt", "File-01.txt", "File-5.txt", "File-007.txt", "File-10.txt"]
let sortedFiles = files.sorted() { $0.compare($1, options: .numeric) == .orderedAscending }
print(sortedFiles) // ["File-01.txt", "File-5.txt", "File-007.txt", "File-10.txt", "File-42.txt"]

Leniwie spłaszczając wielowymiarową tablicę za pomocą spłaszczania ()

Możemy użyć flatten() , aby leniwie zmniejszyć zagnieżdżanie sekwencji wielowymiarowej.

Na przykład leniwe spłaszczanie tablicy 2D do tablicy 1D:

// A 2D array of type [[Int]]
let array2D = [[1, 3], [4], [6, 8, 10], [11]]

// A FlattenBidirectionalCollection<[[Int]]>
let lazilyFlattenedArray = array2D.flatten()

print(lazilyFlattenedArray.contains(4)) // true

W powyższym przykładzie funkcja flatten() zwróci FlattenBidirectionalCollection , która leniwie zastosuje spłaszczanie tablicy. Dlatego contains(_:) będzie wymagał jedynie spłaszczenia pierwszych dwóch zagnieżdżonych tablic array2D - ponieważ spowoduje to zwarcie po znalezieniu pożądanego elementu.

Łączenie elementów tablicy z redukcją (_: Połącz :)

Można reduce(_:combine:) , aby połączyć elementy sekwencji w jedną wartość. Wynik przyjmuje wartość początkową, a także zamknięcie, które ma zastosowanie do każdego elementu - co zwróci nową skumulowaną wartość.

Możemy na przykład użyć go do zsumowania tablicy liczb:

let numbers = [2, 5, 7, 8, 10, 4]

let sum = numbers.reduce(0) {accumulator, element in
    return accumulator + element
}

print(sum) // 36

Podajemy 0 do wartości początkowej, ponieważ jest to logiczna wartość początkowa dla sumowania. Gdybyśmy przekazali wartość N , wynikowa sum wynosiłaby N + 36 . Zamknięcie przekazane w celu reduce ma dwa argumenty. accumulator jest bieżącą zakumulowaną wartością, której przypisuje się wartość zwracaną przez zamknięcie przy każdej iteracji. element jest bieżącym elementem w iteracji.

Jak w tym przykładzie, mijamy zamknięcie (Int, Int) -> Int aby reduce , co jest po prostu wynikiem dodania dwóch danych wejściowych - możemy faktycznie przekazać operator + bezpośrednio, ponieważ operatory są funkcjami w Swift:

let sum = numbers.reduce(0, combine: +)

Usuwanie elementu z tablicy bez znajomości jego indeksu

Zasadniczo, jeśli chcemy usunąć element z tablicy, musimy znać jego indeks, abyśmy mogli go łatwo remove(at:) za pomocą funkcji remove(at:) .

Ale co, jeśli nie znamy indeksu, ale znamy wartość elementu do usunięcia!

Oto proste rozszerzenie tablicy, które pozwoli nam łatwo usunąć element z tablicy bez znajomości jego indeksu:

Swift3

extension Array where Element: Equatable {

    mutating func remove(_ element: Element) {
        _ = index(of: element).flatMap {
            self.remove(at: $0)
        }
    }
}

na przykład

    var array = ["abc", "lmn", "pqr", "stu", "xyz"]
    array.remove("lmn")
    print("\(array)")    //["abc", "pqr", "stu", "xyz"]
    
    array.remove("nonexistent")
    print("\(array)")    //["abc", "pqr", "stu", "xyz"]
    //if provided element value is not present, then it will do nothing!

Również, jeśli przez pomyłkę zrobiliśmy coś takiego: array.remove(25) tj. array.remove(25) wartość o innym typie danych, kompilator zgłosi błąd, mówiąc:
cannot convert value to expected argument type

Znajdowanie minimalnego lub maksymalnego elementu tablicy

2.1 2.2

Możesz użyć minElement() i maxElement() , aby znaleźć minimum lub maksimum elementu w danej sekwencji. Na przykład z tablicą liczb:

let numbers = [2, 6, 1, 25, 13, 7, 9]

let minimumNumber = numbers.minElement() // Optional(1)
let maximumNumber = numbers.maxElement() // Optional(25)
3.0

Od Swift 3 zmieniono nazwy metod na odpowiednio min() i max() :

let minimumNumber = numbers.min() // Optional(1)
let maximumNumber = numbers.max() // Optional(25)

Zwrócone wartości z tych metod są Opcjonalne, aby odzwierciedlić fakt, że tablica może być pusta - jeśli tak, to zwracane jest nil .

Uwaga: powyższe metody wymagają, aby elementy były zgodne z protokołem Comparable .

Znalezienie minimalnego lub maksymalnego elementu za pomocą niestandardowego zamówienia

Możesz również użyć powyższych metod z niestandardowym zamknięciem , określając, czy jeden element powinien być zamówiony przed drugim, umożliwiając znalezienie minimalnego lub maksymalnego elementu w tablicy, w której elementy niekoniecznie są Comparable .

Na przykład za pomocą tablicy wektorów:

struct Vector2 {
    let dx : Double
    let dy : Double
    
    var magnitude : Double {return sqrt(dx*dx+dy*dy)}
}

let vectors = [Vector2(dx: 3, dy: 2), Vector2(dx: 1, dy: 1), Vector2(dx: 2, dy: 2)]
2.1 2.2
// Vector2(dx: 1.0, dy: 1.0)
let lowestMagnitudeVec2 = vectors.minElement { $0.magnitude < $1.magnitude } 

// Vector2(dx: 3.0, dy: 2.0)
let highestMagnitudeVec2 = vectors.maxElement { $0.magnitude < $1.magnitude } 
3.0
let lowestMagnitudeVec2 = vectors.min { $0.magnitude < $1.magnitude }
let highestMagnitudeVec2 = vectors.max { $0.magnitude < $1.magnitude }

Bezpieczny dostęp do indeksów

Dodając następujące rozszerzenie do indeksów tablicowych, można uzyskać dostęp bez wiedzy, czy indeks znajduje się w granicach.

extension Array {
    subscript (safe index: Int) -> Element? {
        return indices ~= index ? self[index] : nil
    }
}

przykład:

if let thirdValue = array[safe: 2] {
    print(thirdValue)
}

Porównywanie 2 tablic z zamkiem

Funkcja zip akceptuje 2 parametry typu SequenceType i zwraca Zip2Sequence gdzie każdy element zawiera wartość z pierwszej sekwencji i jeden z drugiej sekwencji.

Przykład

let nums = [1, 2, 3]
let animals = ["Dog", "Cat", "Tiger"]
let numsAndAnimals = zip(nums, animals)

nomsAndAnimals zawiera teraz następujące wartości

sekwencja 1 sekwencja 1
1 "Dog"
2 "Cat"
3 "Tiger"

Jest to przydatne, gdy chcesz wykonać pewnego rodzaju porównanie n-tego elementu każdej tablicy.

Przykład

Biorąc pod uwagę 2 tablice Int(s)

let list0 = [0, 2, 4]
let list1 = [0, 4, 8]

chcesz sprawdzić, czy każda wartość na list1 jest podwójną wartością list0 na list0 .

let list1HasDoubleOfList0 = !zip(list0, list1).filter { $0 != (2 * $1)}.isEmpty


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow