Czy istnieje odpowiednik w Swift flatten
w Scali, Xtend, Groovy, Ruby i co?
var aofa = [[1,2,3],[4],[5,6,7,8,9]]
aofa.flatten() // shall deliver [1,2,3,4,5,6,7,8,9]
oczywiście mógłbym użyć do tego redukcji, ale to trochę jest do bani
var flattened = aofa.reduce(Int[]()){
a,i in var b : Int[] = a
b.extend(i)
return b
}
Odpowiedzi:
Swift> = 3.0
reduce
:flatMap
:joined
:źródło
flatMap
jest dostępny od wersji Swift 1.2.joined
(formalnie nazywanaflatten
) withflatMap
? Czy to, że podczasflatMap
łączenia może również mapować / przekształcać rzeczy. ale tutaj w przykładzie naprawdę nie potrzebujemy, czyli wracamy$0
flatMap
będzie albo spłaszczenie tablicy 2D w tablicy 1D lub usuninil
wartości nie jednocześnie. Określa, co zrobić na podstawie tego, czy tablica pierwszego poziomuElement
jest tablicą, czy opcjonalna - więc jeśli przekażesz jej tablicę opcji 2D (np.[[Int?]]
) , Zdecyduje się spłaszczyć ją do 1D (np[Int?]
. ) . Aby zarówno spłaszczyć do 1-D, jak i usunąć nile drugiego poziomu, musisz zrobićarray.flatMap { $0 }.flatMap { $0 }
. Innymi słowy, spłaszczenie wymiaru jest równoważne,Array(array.joined())
a „spłaszczenie” z usunięciem zera jest równoważnearray.filter{ $0 != nil }.map{ $0! }
.flatMap
jest nadal odpowiedni do zastosowania opisanego w pytaniu (spłaszczanie tablicy 2D do 1D).compactMap
służy wyraźnie do usuwanianil
elementów z sekwencji, tak jakflatMap
kiedyś.[[Any]]
, aflatMap
po prostu przekształca ją na typ[Any]
([1, 2, 3, 4, [5, 6], 7, 8, 9]). A gdybyśmyflatMap
ponownie złożyli wniosek , działalibyśmy zgodnie z zasadą „Any? typ, gdzie kompilator nie wie już, czy jest to prosta wartość, czy sama tablica.Swift standardowej bibliotece jest
joined
funkcją realizowane dla wszystkich typów zgodnych zSequence
protokołem (alboflatten
naSequenceType
wcześniej Swift 3), który obejmujeArray
:W niektórych przypadkach użycie of
joined()
może być korzystne, ponieważ zwraca leniwą kolekcję zamiast nowej tablicy, ale zawsze można je przekonwertować na tablicę po przekazaniu doArray()
inicjatora, jak w powyższym przykładzie.źródło
FlattenBidirectionalCollection<Array<Array<Int>>>(_base: [[1, 2, 3], [4], [5, 6, 7, 8, 9]]))
. Twój punkt widzenia jest jednak słuszny, że możesz uzyskać do niego dostęp jak do płaskiej tablicy, więc wydawałoby się, żeCustomStringConvertable
implementacja wprowadza w błąd. Twój fragment kodu był i nadal nie ma testu.flatten()
została zmieniona najoined()
Swift 4.x / 5.x
Aby dodać trochę więcej złożoności do tablicy, jeśli istnieje tablica zawierająca tablicę tablic, to
flatMap
faktycznie się nie powiedzie.Załóżmy, że tablicą jest
Co
flatMap
lubcompactMap
zwraca:Aby rozwiązać ten problem, możemy użyć naszej prostej logiki pętli for + rekurencji
Wywołaj więc tę funkcję z podaną tablicą
Wynik to:
Ta funkcja pomoże spłaszczyć każdy rodzaj tablicy, biorąc pod uwagę przypadek
Int
tutajWyjście na plac zabaw:
źródło
Swift 4.x
To użycie
flatMap
nie jest przestarzałe i jest do tego stworzone. https://developer.apple.com/documentation/swift/sequence/2905332-flatmapźródło
Edycja: użyj
joined()
zamiast tego:https://developer.apple.com/documentation/swift/sequence/2431985-joined
Oryginalna odpowiedź:
źródło
Swift 4.2
Poniżej napisałem proste rozszerzenie tablicy. Możesz użyć do spłaszczenia tablicy, która zawiera inną tablicę lub element. w przeciwieństwie do linked () metody.
stosowanie:
źródło
Innym bardziej ogólne wdrażanie
reduce
,Osiąga to to samo, ale może dać lepszy wgląd w to, co się dzieje
reduce
.Z dokumentów Apple,
Opis
Zwróć wynik wielokrotnego wywoływania kombajnu ze skumulowaną wartością zainicjowaną do wartości początkowej i każdego elementu sekwencji po kolei.
źródło
Use of unresolved identifier 'reduce'
Zmodyfikowana odpowiedź @ RahmiBozdag, 1. Metody w rozszerzeniach publicznych są publiczne. 2. Usunięto dodatkową metodę, ponieważ indeks początkowy będzie zawsze wynosił zero. 3. Nie znalazłem sposobu na umieszczenie compactMap wewnątrz dla nil i opcji, ponieważ wewnątrz metody T zawsze jest [Any?], Wszelkie sugestie są mile widziane.
źródło
Możesz spłaszczyć zagnieżdżoną tablicę za pomocą następującej metody:
źródło
Apple Swift w wersji 5.1.2 (swiftlang-1100.0.278 clang-1100.0.33.9)
Cel: x86_64-apple-darwin19.2.0
źródło
Swift 5.1
W przypadku, gdy chcesz go również dla wartości słownika:
źródło
flatten()
został przemianowany najoined()
w Swift 3 na SE-0133:https://github.com/apple/swift-evolution/blob/master/propiments/0133-rename-flatten-to-joined.md
źródło
macierz to [[myDTO]]?
W Swift 5 możesz użyć this = Array (self.matrix! .Joined ())
źródło
źródło