Od wersji Swift 4 możesz to zrobić bardzo łatwo. Istnieją dwa nowe inicjatory, które tworzą słownik z sekwencji krotek (pary klucza i wartości). Jeśli gwarantujemy, że klucze są unikatowe, możesz wykonać następujące czynności:
let persons = [Person(name: "Franz", position: 1),
Person(name: "Heinz", position: 2),
Person(name: "Hans", position: 3)]
Dictionary(uniqueKeysWithValues: persons.map { ($0.position, $0.name) })
=> [1: "Franz", 2: "Heinz", 3: "Hans"]
Jeśli jakikolwiek klucz zostanie zduplikowany, spowoduje to błąd w czasie wykonywania. W takim przypadku możesz użyć tej wersji:
let persons = [Person(name: "Franz", position: 1),
Person(name: "Heinz", position: 2),
Person(name: "Hans", position: 1)]
Dictionary(persons.map { ($0.position, $0.name) }) { _, last in last }
=> [1: "Hans", 2: "Heinz"]
Zachowuje się jak pętla for. Jeśli nie chcesz „zastępować” wartości i trzymać się pierwszego mapowania, możesz użyć tego:
Dictionary(persons.map { ($0.position, $0.name) }) { first, _ in first }
=> [1: "Franz", 2: "Heinz"]
Swift 4.2 dodaje trzeci inicjator, który grupuje elementy sekwencji w słowniku. Klucze słownika są wyprowadzane przez zamknięcie. Elementy z tym samym kluczem są umieszczane w tablicy w tej samej kolejności, co w sekwencji. Pozwala to na osiągnięcie podobnych rezultatów jak powyżej. Na przykład:
Dictionary(grouping: persons, by: { $0.position }).mapValues { $0.last! }
=> [1: Person(name: "Hans", position: 1), 2: Person(name: "Heinz", position: 2)]
Dictionary(grouping: persons, by: { $0.position }).mapValues { $0.first! }
=> [1: Person(name: "Franz", position: 1), 2: Person(name: "Heinz", position: 2)]
[position:name]
czy[position:[name]]
? Jeśli masz dwie osoby na tej samej pozycji, Twój słownik zachowa tylko ostatnią napotkaną w Twojej pętli ... Mam podobne pytanie, na które próbuję znaleźć rozwiązanie, ale chcę, aby wynik był podobny[1: [p1, p3], 2: [p2]]