如何在Swift中串联或合并数组?


Answers:


691

您可以使用串联数组+,建立一个新数组

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]

[AnyObect]?与CGFloat不同。在连接到AnyObject数组时。
khunshan 2014年

6
Khunshan:AnyObject表示一个对象,据我了解,它是指从类类型实例化的对象。CGFloat不是对象,而是标量值。据我了解,数组可以包含标量,除非将其定义为包含标量AnyObject或进一步完善。但是,我怀疑这里的问题是数组包装在一个可选包装中,因此您必须先用!或将其拆开?
Owen Godfrey 2014年

我们是否知道Swift 2的写时复制智能是否扩展到确定的b一部分是否a被修改(因此有可能b在期间删除的副本a.appendContentsOf(b))?
Ephemera 2015年

1
@OwenGodfrey谢谢。我对appendContentsOf和insertContentsOf感到困惑。
khunshan '16


137

使用Swift 5,您可以根据需要选择以下六种方法之一来串联/合并两个数组。


#1。使用Array+(_:_:)通用运算符将两个数组合并为一个新数组

Array有一个+(_:_:)通用运算符。+(_:_:)具有以下声明

通过将集合的元素和序列连接起来,创建一个新的集合。

static func + <Other>(lhs: Array<Element>, rhs: Other) -> Array<Element> where Other : Sequence, Self.Element == Other.Element

以下Playground示例代码显示了如何使用以下命令将两个类型的数组合并[Int]为一个新数组+(_:_:)通用运算符:

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+=(_:_:)通用运算符

Array有一个+=(_:_:)通用运算符。+=(_:_:)具有以下声明

将序列的元素追加到范围可替换的集合中。

static func += <Other>(lhs: inout Array<Element>, rhs: Other) where Other : Sequence, Self.Element == Other.Element

以下Playground示例代码显示了如何[Int]使用+=(_:_:)泛型运算符将类型数组的元素附加到现有数组中:

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

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

#3。将一个数组附加到另​​一个数组Arrayappend(contentsOf:)方法

Swift Array有一个append(contentsOf:)方法。append(contentsOf:)具有以下声明

将序列或集合的元素添加到此集合的末尾。

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

以下Playground示例代码展示了如何[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]

#4。将两个数组合并为一个新数组SequenceflatMap(_:)方法将

Swift为flatMap(_:)符合Sequence协议(包括Array)的所有类型提供了一种方法。flatMap(_:)具有以下声明

返回一个包含此序列的每个元素的调用给定转换的串联结果的数组。

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

以下Playground示例代码显示了如何[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]

#5。合并两个阵列与一个新的数组Sequencejoined()方法和初始化器将Arrayinit(_:)

Swift为joined()符合Sequence协议(包括Array)的所有类型提供了一种方法。joined()有以下声明

返回此序列序列的元素,串联在一起。

func joined() -> FlattenSequence<Self>

此外,Swift Array有一个init(_:)初始化程序。init(_:)具有以下声明

创建一个包含序列元素的数组。

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

因此,以下Playground示例代码展示了如何[Int]使用joined()method和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]

#6。使用Arrayreduce(_:_:)方法将两个数组合并为一个新数组

雨燕Array有一种reduce(_:_:)方法。reduce(_:_:)具有以下声明

返回使用给定的闭包组合序列元素的结果。

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

以下Playground代码显示了如何[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]

5
感谢您分享此代码,良好的解释,仅添加答案,如果您说哪个在性能上更有效,那将是最好的选择?
kokemomuke

我喜欢+2个数组和joined()一个数组。
心教堂

如果要合并两个以上的数组(或字符串或其他东西),限制自己使用+运算符,那么它将产生绝对疯狂的编译时间。
lawicko

@lawicko您会推荐哪种方法?
Cyber​​Mew

@Cyber​​Mew任何不使用重载运算符的东西,我喜欢方法3,因为我认为它最易读,但我也喜欢平面地图中的方法4。对于字符串,我喜欢方法5,因为最后您会立即获得连接的字符串。
lawicko

34

如果您不是运算符重载的忠实拥护者,或者不是更多的功能类型:

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

22

自从Swift 2.0 展平以来,我最喜欢的方法

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())

2
flatten()如今似乎不再存在。但是你可以考虑一下joined()
心教堂

13

为了完成可能的选择列表,reduce可以用来实现flatten的行为:

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

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

在介绍的方法中,最好的替代方法(从性能/内存角度flatten来看)很简单,即只是懒散地包装原始数组,而无需创建新的数组结构。

但是请注意,扁平化 不返回一个LazyCollection,让懒惰行为不会传播到沿链(地图,flatMap,过滤器,等...)下一步的操作。

如果在您的特定情况下懒惰是有意义的,则只需记住在前面加上或.lazy即可flatten(),例如,以这种方式修改Tomasz示例:

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

在Swift 5.1中,这个答案在2019年仍然有多好?
willbattel

flatten()不再存在。可以使用
join

4

如果要在特定索引之后插入第二个数组,可以执行以下操作(从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] 

4

斯威夫特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]

这是上述代码的正确结果。


4
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)

上面的代码将在arrayTwo的末尾添加arrayOne的所有元素。

谢谢。


4

斯威夫特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 :)

3

这是合并两个数组的最短方法。

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

串联/合并它们

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

1

同样,使用数组的字典可以:

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(如果“键”匹配)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.