Как объединить или объединить массивы в Swift?

319

Если есть два массива, созданных в swift следующим образом:

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

Как они могут быть объединены с [1, 2, 3, 4, 5, 6]?

Теги:
arrays
merge
append

12 ответов

576
Лучший ответ

Вы можете объединить массивы с помощью +, создав новый массив

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

или добавить один массив к другому с помощью += (или 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]
  • 0
    [AnyObect]? не идентичен CGFloat. При конкатенации к массивам AnyObject.
  • 6
    Khunshan: AnyObject указывает на объект, который, как я понимаю, означает что-то, что создается из типа класса. CGFloat - это не объект, это скалярное значение. Насколько я понимаю, массивы могут содержать скаляры, если только он не определен как содержащий AnyObject или не уточнен. Тем не менее, я подозреваю, что проблема заключается в том, что массив обернут в необязательный, поэтому вы должны развернуть его с ! или ? первый.
Показать ещё 8 комментариев
91

С Swift 3, в соответствии с вашими потребностями и вкусами, вы можете выбрать один из пяти следующих способов, чтобы объединить/объединить два массива.


1. Объедините два массива в новый массив с Swift standard library +(_:_:) общим оператором

Стандартная библиотека Swift определяет оператор +(_:_:) generic. +(_:_:) имеет следующее объявление:

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

Создает новую коллекцию, объединяя элементы двух коллекций.

Следующий код игровой площадки показывает, как объединить два массива типа [Int] в новый массив с помощью +(_:_:) generic operator:

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

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

2. Добавить массив в другой массив с помощью метода Array append(contentsOf:)

Swift Array имеет метод append(contentsOf:). append(contentsOf:) имеет следующее объявление:

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

Добавляет элементы последовательности или коллекции в конец этой коллекции.

Следующий код игровой площадки показывает, как добавить массив к другому массиву типа [Int] с помощью метода 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. Объедините два массива в новый массив с помощью метода Sequence flatMap(_:)

Swift предоставляет метод flatMap(_:) для всех типов, соответствующих протоколу Sequence (включая Array). flatMap(_:) имеет следующее объявление:

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

Возвращает массив, содержащий конкатенированные результаты вызова данного преобразования с каждым элементом этой последовательности.

Следующий код игровой площадки показывает, как объединить два массива типа [Int] в новый массив с использованием метода 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. Объедините два массива в новый массив с помощью метода Sequence joined() и Array init(_:) инициализатор

Swift предоставляет метод joined() для всех типов, соответствующих протоколу Sequence (включая Array). joined() имеет следующее объявление:

func joined() -> FlattenSequence<Self>

Возвращает элементы этой последовательности последовательностей, конкатенированные.

Кроме того, Swift Array имеет инициализатор init(_:). init(_:) имеет следующее объявление:

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

Создает массив, содержащий элементы последовательности.

Поэтому следующий код площадки показывает, как объединить два массива типа [Int] в новый массив с использованием метода joined() и init(_:) initializer:

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. Объедините два массива в новый массив с помощью метода Array reduce(_:_:)

Swift Array имеет метод reduce(_:_:). reduce(_:_:) имеет следующее объявление:

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

Возвращает результат вызова данного объединения с каждым элементом этой последовательности и накоплением.

Следующий код игровой площадки показывает, как объединить два массива типа [Int] в новый массив с помощью метода 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]
  • 3
    спасибо, что поделились этим кодом, хорошее объяснение, просто добавление к вашему ответу, было бы лучше, если бы вы сказали, какой из них более эффективен по производительности?
28

Если вы не большой поклонник перегрузки операторов или просто более функционального типа:

// 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]
19

Мой любимый метод, так как Swift 2.0 flatten

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

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

Это вернет FlattenBidirectionalCollection, поэтому, если вы просто хотите CollectionType, этого будет достаточно, и вы получите ленивую оценку бесплатно. Если вам нужен именно массив, вы можете сделать это:

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

Чтобы завершить список возможных альтернатив, reduce может использоваться для реализации поведения flatten:

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

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

Лучшей альтернативой (производительность/память) среди представленных является просто flatten, которые лениво завершают оригинальные массивы, не создавая новую структуру массива.

Но обратите внимание, что flatten не возвращает a LazyColletion, поэтому ленивое поведение не будет распространяться на следующую операцию вдоль цепочки (map, flatMap, filter и т.д.).

Если ленивость имеет смысл в вашем конкретном случае, просто не забудьте добавить или добавить .lazy в flatten(), например, модифицируя образец Tomasz таким образом:

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

Swift 3.0

Вы можете создать новый массив, объединив два существующих массива с совместимыми типами с оператором сложения (+). Новый тип массива выводится из типа двух массивов, которые вы добавляете вместе,

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]

это правильный результат приведенных выше кодов.

3

Если вы хотите, чтобы второй массив был вставлен после определенного индекса, вы можете сделать это (с 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] 
2
var arrayOne = [1,2,3]
var arrayTwo = [4,5,6]

если вы хотите результат как: [1,2,3, [4,5,6]]

arrayOne.append(arrayTwo)

Приведенный выше код преобразует arrayOne как отдельный элемент и добавит его в конец arrayTwo.

если вы хотите результат как: [1, 2, 3, 4, 5, 6], то

arrayOne.append(contentsOf: arrayTwo)

Приведенный выше код добавит все элементы arrayOne в конец arrayTwo.

Благодарю.

2

Здесь самый короткий способ слияния двух массивов.

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

Объединить/объединить их

array1 += array2
New value of array1 is [1,2,3,4,5,6]
0

Swift 4.X

Самый простой способ, который я знаю, это просто использовать знак +

var Array1 = ["Item 1", "Item 2"]
var Array2 = ["Thing 1", "Thing 2"]

var Array3 = Array1 + Array2

// Array 3 will just be them combined :)
0

Аналогично со словарями массивов можно:

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"]!)

и вы можете перебрать dict1 и добавить dict2, если "ключ" совпадает

0

Marge массив, который представляет собой разные типы данных:

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

Выход:

["a", true, 3, "b", "hi", 3, [6]]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню