Comment concaténer ou fusionner des tableaux dans Swift?

S'il y a deux tableaux créés dans swift comme ceci:

var a:[CGFloat] = [1, 2, 3]
var b:[CGFloat] = [4, 5, 6]

Comment peuvent-ils être fusionnés en [1, 2, 3, 4, 5, 6]?

302
demandé sur D A Vincent 2014-08-05 23:02:26

10 réponses

Vous pouvez concaténer les tableaux avec +, en construisant un nouveau tableau

let c = a + b
print(c) // [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]

Ou ajouter un tableau à l'autre avec += (ou append):

a += b

// Or:
a.append(contentsOf: b)  // Swift 3
a.appendContentsOf(b)    // Swift 2
a.extend(b)              // Swift 1.2

print(a) // [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
544
répondu Martin R 2017-12-12 09:13:31

Avec Swift 3, selon vos besoins et vos goûts, vous pouvez choisir l'une des cinq façons suivantes de concaténer / fusionner deux tableaux.


1. Fusionner deux tableaux dans un nouveau tableau avec Swift standard library'S +(_:_:) opérateur Générique

La bibliothèque standard Swift définit un opérateur Générique +(_:_:). +(_:_:) a la déclaration suivante :

func +<RRC1 : RangeReplaceableCollection, RRC2 : RangeReplaceableCollection where RRC1.Iterator.Element == RRC2.Iterator.Element>(lhs: RRC1, rhs: RRC2) -> RRC1

Crée une nouvelle collection en concaténant les éléments de deux collections.

Le le code de terrain de jeu suivant montre comment fusionner deux tableaux de type [Int] dans un nouveau tableau en utilisant l'opérateur Générique +(_:_:):

let array1 = [1, 2, 3]
let array2 = [4, 5, 6]

let flattenArray = array1 + array2
print(flattenArray) // prints [1, 2, 3, 4, 5, 6]

2. Ajouter un tableau à un autre tableau avec la méthode Array de append(contentsOf:)

Swift Array a une méthode append(contentsOf:). append(contentsOf:) a la déclaration suivante :

public mutating func append<S>(contentsOf newElements: S) where S : Sequence, S.Iterator.Element == Element)

Ajoute les éléments d'une séquence ou d'une collection à la fin de cette collection.

Le code Playground suivant montre comment ajouter un tableau à un autre tableau de type [Int] utilisant la méthode append(contentsOf:):

var array1 = [1, 2, 3]
let array2 = [4, 5, 6]

array1.append(contentsOf: array2)
print(array1) // prints [1, 2, 3, 4, 5, 6]

3. Fusionnez deux tableaux dans un nouveau tableau avec la méthode flatMap(_:)

Swift fournit une méthode flatMap(_:) pour tous les types conformes au protocole Sequence (y compris Array). flatMap(_:) a la déclaration suivante :

func flatMap<SegmentOfResult : Sequence>(_ transform: (Self.Iterator.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Iterator.Element]

Renvoie un tableau contenant les résultats concaténés de l'appel de la transformation donnée avec chaque élément de cette séquence.

Ce qui suit Le code Playground montre comment fusionner deux tableaux de type [Int] dans un nouveau tableau en utilisant la méthode flatMap(_:):

let array1 = [1, 2, 3]
let array2 = [4, 5, 6]

let flattenArray = [array1, array2].flatMap({ (element: [Int]) -> [Int] in
    return element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6]

4. Fusionnez deux tableaux dans un nouveau tableau avec la méthode Sequence joined() et l'initialiseur Array init(_:)

Swift fournit une méthode joined() pour tous les types conformes au protocole Sequence (y compris Array). joined() a la déclaration suivante :

func joined() -> FlattenSequence<Self>

Renvoie les éléments de cette séquence de séquences, concaténées.

En Outre, Swift Array est un init(_:) initialiseur. init(_:) a la déclaration suivante :

init<S : Sequence where S.Iterator.Element == Element>(_ s: S)

Crée un tableau contenant les éléments d'une séquence.

Par conséquent, le code Playground suivant montre comment fusionner deux tableaux de type [Int] dans un nouveau tableau en utilisant la méthode joined() et l'initialiseur init(_:):

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]

5. Fusionner deux tableaux dans un nouveau tableau avec Array méthode reduce(_:_:)

Swift Array est un reduce(_:_:) méthode. reduce(_:_:) a la déclaration suivante :

func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result

Renvoie le résultat de l'appel de la fermeture de combinaison donnée avec chaque élément de cette séquence et une valeur accumulée.

Le code Playground suivant montre comment fusionner deux tableaux de type [Int] dans un nouveau tableau en utilisant la méthode reduce(_:_:):

let array1 = [1, 2, 3]
let array2 = [4, 5, 6]

let flattenArray = [array1, array2].reduce([], { (result: [Int], element: [Int]) -> [Int] in
    return result + element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6]
91
répondu Imanou Petit 2017-08-09 22:19:32

Si vous n'êtes pas un grand fan de la surcharge de l'opérateur, ou juste plus d'un type fonctionnel:

// 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]
25
répondu Mazyod 2018-05-14 04:39:28

Ma méthode préférée depuis Swift 2.0 est aplatir

var a:[CGFloat] = [1, 2, 3]
var b:[CGFloat] = [4, 5, 6]

let c = [a, b].flatten()

Cela retournera FlattenBidirectionalCollection donc si vous voulez juste un CollectionType cela suffira et vous aurez une évaluation paresseuse gratuitement. Si vous avez besoin exactement du tableau, vous pouvez le faire:

let c = Array([a, b].flatten())
19
répondu Tomasz Bąk 2015-12-02 08:01:38

Pour compléter la liste des alternatives possibles, reduce pourrait être utilisé pour implémenter le comportement de aplatir :

var a = ["a", "b", "c"] 
var b = ["d", "e", "f"]

let res = [a, b].reduce([],combine:+)

La meilleure alternative (performance/Mémoire) parmi celles présentées est simplement flatten, qui enveloppent simplement les tableaux d'origine paresseusement sans créer une nouvelle structure de tableau.

Mais notez que aplatir ne retourne pas a LazyColletion, de sorte que le comportement paresseux ne sera pas propagé à l'opération suivante le long de la chaîne (map, flatMap, filtre, etc...).

Si la lazyness a du sens dans votre cas particulier, n'oubliez pas d'ajouter ou d'ajouter un .lazy à flatten(), par exemple, en modifiant L'exemple Tomasz de cette façon:

let c = [a, b].lazy.flatten() 
9
répondu Umberto Raimondi 2015-12-28 14:44:17

Si vous voulez que le deuxième tableau soit inséré après un index particulier, vous pouvez le faire (à partir de Swift 2.2):

let index = 1
if 0 ... a.count ~= index {
     a[index..<index] = b[0..<b.count]
}
print(a) // [1.0, 4.0, 5.0, 6.0, 2.0, 3.0] 
3
répondu Vitalii 2016-05-25 13:48:26

Swift 3.0

Vous pouvez créer un nouveau tableau en ajoutant deux tableaux existants avec des types compatibles avec l'opérateur d'addition (+). Le type du nouveau tableau est déduit du type des deux tableaux que vous ajoutez ensemble,

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]

Ce sont les bons résultats des codes ci-dessus.

3
répondu Xinyang Li 2017-05-25 15:06:16

Voici le moyen le plus court de fusionner deux tableaux.

 var array1 = [1,2,3]
 let array2 = [4,5,6]

Concaténer / fusionner les

array1 += array2
New value of array1 is [1,2,3,4,5,6]
2
répondu handiansom 2017-07-30 21:13:02

Tableau Marge qui sont différents types de données:

var arrayInt = [Int]()
arrayInt.append(6)
var testArray = ["a",true,3,"b"] as [Any]
testArray.append(someInt)

Sortie :

["a", true, 3, "b", "hi", 3, [6]]
0
répondu Abhishek Gupta 2017-02-08 11:23:14

De même, avec les dictionnaires de tableaux on peut:

var dict1 = [String:[Int]]()
var dict2 = [String:[Int]]()
dict1["key"] = [1,2,3]
dict2["key"] = [4,5,6]
dict1["key"] = dict1["key"]! + dict2["key"]!
print(dict1["key"]!)

Et vous pouvez parcourir dict1 et ajouter dict2 si la "clé" correspond à

0
répondu Jeremy Andrews 2018-08-06 17:36:26