[AnyObect]? nie jest identyczny z CGFloat. Podczas łączenia z tablicami AnyObject.
khunshan
6
Khunshan: AnyObjectwskazuje obiekt, który, jak rozumiem, oznacza coś, co jest tworzone z typu klasy. CGFloatnie jest przedmiotem, to wartość skalarna. Jak rozumiem, tablice mogą zawierać skalary, chyba że są zdefiniowane jako zawierające AnyObjectlub są dalej ulepszane. Jednak podejrzewam tu problemem jest to, że tablica jest owinięty w opcjonalny, więc trzeba rozpakować go !lub ?pierwszy.
Owen Godfrey
Czy wiemy, czy inteligencja Swift 2 Copy-On-Write rozciąga się na ustalenie, czy bczęść ajest modyfikowana (a zatem może pomijać kopię bpodczas a.appendContentsOf(b))?
Efemeryda
1
@OwenGodfrey dzięki. mam mylące zdanie na temat appendContentsOf i insertContentsOf.
Poniższy przykładowy kod Playground pokazuje, jak połączyć dwie tablice typu [Int]w nową tablicę przy użyciu flatMap(_:)metody:
let array1=[1,2,3]let array2=[4,5,6]let flattenArray =[array1, array2].flatMap({(element:[Int])->[Int]inreturn element
})
print(flattenArray)// prints [1,2,3,4,5,6]
# 5. Łączy dwie matryce do nowej tablicy z Sequence's joined()sposobem i Arrayjest init(_:)inicjator
Swift zapewnia joined()metodę dla wszystkich typów zgodnych z Sequenceprotokołem (w tym Array). joined()ma następującą deklarację :
Zwraca elementy tej sekwencji sekwencji, połączone.
func joined()->FlattenSequence<Self>
Poza tym Swift Arrayma init(_:)inicjalizator. init(_:)ma następującą deklarację :
Tworzy tablicę zawierającą elementy sekwencji.
init<S>(_ s: S)whereElement== S.Element, S :Sequence
Dlatego poniższy przykładowy kod Playground pokazuje, jak połączyć dwie tablice typu [Int]w nową tablicę przy użyciu joined()metody i init(_:)inicjalizatora:
let array1=[1,2,3]let array2=[4,5,6]let flattenCollection =[array1, array2].joined()// type: FlattenBidirectionalCollection<[Array<Int>]>
let flattenArray =Array(flattenCollection)
print(flattenArray)// prints [1,2,3,4,5,6]
# 6. Łączy dwie matryce do nowej tablicy z Array„s reduce(_:_:)metody
Swift Arrayma reduce(_:_:)metodę. reduce(_:_:)ma następującą deklarację :
Zwraca wynik łączenia elementów sekwencji przy użyciu danego zamknięcia.
Poniższy kod Playground pokazuje, jak połączyć dwie tablice typu [Int]w nową tablicę przy użyciu reduce(_:_:)metody:
let array1=[1,2,3]let array2=[4,5,6]let flattenArray =[array1, array2].reduce([],{(result:[Int], element:[Int])->[Int]inreturn result + element
})
print(flattenArray)// prints [1,2,3,4,5,6]
dziękuję za udostępnienie tego kodu, dobre wyjaśnienie, wystarczy dodać do swojej odpowiedzi, najlepiej byłoby, gdybyś powiedział, który z nich jest bardziej wydajny pod względem wydajności?
kokemomuke
Lubię +2 tablice i joined()tablicę tablic.
Cœur
Jeśli scalasz więcej niż 2 tablice (lub łańcuchy lub cokolwiek innego), powstrzymaj się od korzystania z +operatora, generuje to absolutnie szalone czasy kompilacji.
lawicko
@lawicko, którą metodę polecisz?
CyberMew
@CyberMew Wszystko, co nie używa przeciążonych operatorów, podoba mi się metoda nr 3, ponieważ myślę, że jest najbardziej czytelna, ale lubię także metodę nr 4 z płaską mapą. W przypadku ciągów podoba mi się metoda nr 5, ponieważ na końcu otrzymujesz połączony ciąg od razu.
lawicko
34
Jeśli nie jesteś wielkim fanem przeciążania operatora lub po prostu bardziej funkcjonalnym typem:
// use flatMap
let result =[["merge","me"],["We","shall","unite"],["magic"]].flatMap { $0}// Output: ["merge", "me", "We", "shall", "unite", "magic"]
// ... or reduce
[[1],[2],[3]].reduce([],+)//Output:[1,2,3]
Moją ulubioną metodą od czasu Swift 2.0 jest spłaszczenie
var a:[CGFloat]=[1,2,3]var b:[CGFloat]=[4,5,6]let c =[a, b].flatten()
To wróci, FlattenBidirectionalCollectionwięc jeśli chcesz, CollectionTypewystarczy i będziesz miał leniwą ocenę za darmo. Jeśli potrzebujesz dokładnie tablicy, możesz to zrobić:
flatten()wydaje się, że już nie istnieje. Ale możesz to rozważyć joined().
Cur
13
Aby uzupełnić listę możliwych alternatyw, reducemożna zastosować implementację zachowania spłaszczania :
var a =["a","b","c"]var b =["d","e","f"]let res =[a, b].reduce([],combine:+)
Najlepszą alternatywą (pod względem wydajności / pamięci) spośród przedstawionych jest po flattenprostu leniwe owijanie oryginalnych tablic bez tworzenia nowej struktury tablic.
Ale zauważ, że spłaszczenie nie zwraca a LazyCollection, więc leniwe zachowanie nie zostanie propagowane do następnej operacji wzdłuż łańcucha (mapa, flatMap, filtr itp.).
Jeśli lazyness sens w danym przypadku, po prostu pamiętać, aby poprzedzić lub dołączania .lazydo flatten(), na przykład, modyfikując Tomasz próbkę w ten sposób:
Możesz utworzyć nową tablicę, dodając dwie istniejące tablice z kompatybilnymi typami za pomocą operatora add ( +). Typ nowej tablicy wynika z typu dwóch dodanych razem tablic,
let arr0=Array(repeating:1, count:3)// [1, 1, 1]
let arr1=Array(repeating:2, count:6)//[2, 2, 2, 2, 2, 2]
let arr2= arr0+ arr1//[1,1,1,2,2,2,2,2,2]
Odpowiedzi:
Możesz łączyć tablice
+
, budując nową tablicęlub dołącz jedną tablicę do drugiej za pomocą
+=
(lubappend
):źródło
AnyObject
wskazuje obiekt, który, jak rozumiem, oznacza coś, co jest tworzone z typu klasy.CGFloat
nie jest przedmiotem, to wartość skalarna. Jak rozumiem, tablice mogą zawierać skalary, chyba że są zdefiniowane jako zawierająceAnyObject
lub są dalej ulepszane. Jednak podejrzewam tu problemem jest to, że tablica jest owinięty w opcjonalny, więc trzeba rozpakować go!
lub?
pierwszy.b
częśća
jest modyfikowana (a zatem może pomijać kopięb
podczasa.appendContentsOf(b)
)?W Swift 5, zgodnie z własnymi potrzebami, możesz wybrać jeden z sześciu poniższych sposobów łączenia / łączenia dwóch tablic.
# 1. Łączy dwie matryce do nowej tablicy z
Array
„s+(_:_:)
operatora rodzajowegoArray
ma+(_:_:)
ogólny operator.+(_:_:)
ma następującą deklarację :Poniższy przykładowy kod Playground pokazuje, jak połączyć dwie tablice typu
[Int]
w nową tablicę za pomocą+(_:_:)
operatora ogólnego:# 2. Dołączyć elementy tablicy w istniejącej matrycy z
Array
„S+=(_:_:)
operatora rodzajowegoArray
ma+=(_:_:)
ogólny operator.+=(_:_:)
ma następującą deklarację :Poniższy przykładowy kod Playground pokazuje, jak dołączyć elementy tablicy typu
[Int]
do istniejącej tablicy za pomocą+=(_:_:)
operatora ogólnego:# 3. Dołączania matrycy na drugiej tablicy o
Array
„sappend(contentsOf:)
metodySwift
Array
maappend(contentsOf:)
metodę.append(contentsOf:)
ma następującą deklarację :Poniższy przykładowy kod Playground pokazuje, jak dołączyć tablicę do innej tablicy typu
[Int]
za pomocąappend(contentsOf:)
metody:# 4. Łączy dwie matryce do nowej tablicy z
Sequence
„sflatMap(_:)
metodySwift zapewnia
flatMap(_:)
metodę dla wszystkich typów zgodnych zSequence
protokołem (w tymArray
).flatMap(_:)
ma następującą deklarację :Poniższy przykładowy kod Playground pokazuje, jak połączyć dwie tablice typu
[Int]
w nową tablicę przy użyciuflatMap(_:)
metody:# 5. Łączy dwie matryce do nowej tablicy z
Sequence
'sjoined()
sposobem iArray
jestinit(_:)
inicjatorSwift zapewnia
joined()
metodę dla wszystkich typów zgodnych zSequence
protokołem (w tymArray
).joined()
ma następującą deklarację :Poza tym Swift
Array
mainit(_:)
inicjalizator.init(_:)
ma następującą deklarację :Dlatego poniższy przykładowy kod Playground pokazuje, jak połączyć dwie tablice typu
[Int]
w nową tablicę przy użyciujoined()
metody iinit(_:)
inicjalizatora:# 6. Łączy dwie matryce do nowej tablicy z
Array
„sreduce(_:_:)
metodySwift
Array
mareduce(_:_:)
metodę.reduce(_:_:)
ma następującą deklarację :Poniższy kod Playground pokazuje, jak połączyć dwie tablice typu
[Int]
w nową tablicę przy użyciureduce(_:_:)
metody:źródło
+
2 tablice ijoined()
tablicę tablic.+
operatora, generuje to absolutnie szalone czasy kompilacji.Jeśli nie jesteś wielkim fanem przeciążania operatora lub po prostu bardziej funkcjonalnym typem:
źródło
Moją ulubioną metodą od czasu Swift 2.0 jest spłaszczenie
To wróci,
FlattenBidirectionalCollection
więc jeśli chcesz,CollectionType
wystarczy i będziesz miał leniwą ocenę za darmo. Jeśli potrzebujesz dokładnie tablicy, możesz to zrobić:źródło
flatten()
wydaje się, że już nie istnieje. Ale możesz to rozważyćjoined()
.Aby uzupełnić listę możliwych alternatyw,
reduce
można zastosować implementację zachowania spłaszczania :Najlepszą alternatywą (pod względem wydajności / pamięci) spośród przedstawionych jest po
flatten
prostu leniwe owijanie oryginalnych tablic bez tworzenia nowej struktury tablic.Ale zauważ, że spłaszczenie nie zwraca a
LazyCollection
, więc leniwe zachowanie nie zostanie propagowane do następnej operacji wzdłuż łańcucha (mapa, flatMap, filtr itp.).Jeśli lazyness sens w danym przypadku, po prostu pamiętać, aby poprzedzić lub dołączania
.lazy
doflatten()
, na przykład, modyfikując Tomasz próbkę w ten sposób:źródło
Jeśli chcesz wstawić drugą tablicę po określonym indeksie, możesz to zrobić (od Swift 2.2):
źródło
Swift 3.0
Możesz utworzyć nową tablicę, dodając dwie istniejące tablice z kompatybilnymi typami za pomocą operatora add (
+
). Typ nowej tablicy wynika z typu dwóch dodanych razem tablic,to są prawidłowe wyniki powyższych kodów.
źródło
jeśli chcesz wynik jako: [1,2,3, [4,5,6]]
powyższy kod skonwertuje arrayOne jako pojedynczy element i doda go na końcu arrayTwo.
jeśli chcesz wynik jako: [1, 2, 3, 4, 5, 6], to,
powyższy kod doda wszystkie elementy arrayOne na końcu arrayTwo.
Dzięki.
źródło
Swift 4.X
Najprościej wiem, jak użyć znaku +
źródło
Oto najkrótszy sposób na połączenie dwóch tablic.
Połącz je / połącz
źródło
Podobnie w słownikach tablic można:
i możesz iterować po dict1 i dodać dict2, jeśli „klucz” pasuje
źródło
Marge array, które są różnymi typami danych:
Wynik :
źródło