Swift'te dizileri nasıl birleştirebilirim veya birleştirebilirim?


Yanıtlar:


691

Dizileri birleştirerek +yeni bir dizi oluşturabilirsiniz

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

veya +=(veya append) ile bir diziyi diğerine ekleyin :

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 ile aynı değildir. AnyObject dizilerini birleştirirken.
khunshan

6
Khunshan: AnyObjectbir nesneyi gösterir, ki anladığım kadarıyla bir sınıf türünden başlatılan bir şey anlamına gelir. CGFloatbir nesne değil, skaler bir değerdir. Anladığım kadarıyla, diziler, içerme olarak tanımlanmadığı AnyObjectveya daha fazla rafine edilmediği sürece, skaler içerebilir . Ancak, burada sorun dizi isteğe bağlı olarak sarılmış olduğundan şüpheleniyorum, bu yüzden !ya da ?ilk ile paketini açmak zorunda .
Owen Godfrey

Biz Swift 2'nin Kopya-On-Yaz istihbarat olmadığının belirlenmesinde kadar uzanır olmadığını biliyor musunuz bparçası adeğiştirilir (bu nedenle muhtemelen bir kopyasını eliding bsırasında a.appendContentsOf(b))?
Ephemera

1
@OwenGodfrey teşekkürler. appendContentsOf ve insertContentsOf üzerinde lil karışıklığı var.
khunshan


137

Swift 5 ile, ihtiyaçlarınıza göre, iki diziyi birleştirmek / birleştirmek için aşağıdaki altı yoldan birini seçebilirsiniz .


# 1. Array'S +(_:_:)genel jeneratörü ile iki diziyi yeni bir diziye birleştir

ArrayBir sahiptir +(_:_:)jenerik operatörü. +(_:_:)aşağıdaki beyanı içerir :

Bir koleksiyonun ve sıralamanın öğelerini birleştirerek yeni bir koleksiyon oluşturur.

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

Aşağıdaki Playground örnek kodu, genel işleç [Int]kullanarak iki tür dizinin yeni bir diziye nasıl birleştirileceğini gösterir +(_:_:):

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

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

# 2. Var olan bir diziye bir dizinin elemanları ekleme Array'in +=(_:_:)genel operatör

ArrayBir sahiptir +=(_:_:)jenerik operatörü. +=(_:_:)aşağıdaki beyanı içerir :

Bir dizinin elemanlarını aralıkla değiştirilebilir bir koleksiyona ekler.

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

Aşağıdaki Playground örnek kodu, tür operatörünü [Int]kullanarak bir tür dizisinin öğelerinin mevcut bir diziye nasıl ekleneceğini gösterir +=(_:_:):

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

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

3.. Array'S append(contentsOf:)yöntemiyle başka bir diziye dizi ekleme

Swift'in Arraybir append(contentsOf:)yöntemi var. append(contentsOf:)aşağıdaki beyanı içerir :

Bir dizinin veya koleksiyonun öğelerini bu koleksiyonun sonuna ekler.

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

Aşağıdaki Playground örnek kodu, yöntemi [Int]kullanarak bir dizinin başka bir tür diziye nasıl ekleneceğini gösterir 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.. Sequence' Dizisi flatMap(_:)yöntemiyle iki diziyi yeni bir diziye birleştir

Swift, protokole (dahil ) flatMap(_:)uyan tüm tipler için bir yöntem sağlar . aşağıdaki beyanı içerir :SequenceArrayflatMap(_:)

Bu dizinin her bir elemanı ile verilen dönüşümü çağırmanın birleştirilmiş sonuçlarını içeren bir dizi döndürür.

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

Aşağıdaki Playground örnek kodu, iki tür [Int]dizinin flatMap(_:)yöntemi kullanarak yeni bir diziye nasıl birleştirileceğini gösterir :

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.. İki diziyi Sequence's joined()yöntemi ve Array' init(_:)başlatıcısı ile yeni bir diziye birleştir

Swift, protokole (dahil ) joined()uyan tüm tipler için bir yöntem sağlar . aşağıdaki beyanı içerir :SequenceArrayjoined()

Bu diziler dizisinin birleştirilmiş öğelerini döndürür.

func joined() -> FlattenSequence<Self>

Ayrıca Swift'in Arraybir init(_:)başlatıcısı var. init(_:)aşağıdaki beyanı içerir :

Bir dizinin öğelerini içeren bir dizi oluşturur.

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

Bu nedenle, aşağıdaki Playground örnek kodu, yöntem ve başlatıcı [Int]kullanarak iki tür dizinin yeni bir diziye nasıl birleştirileceğini gösterir :joined()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]

6.. Array' Dizisi reduce(_:_:)yöntemiyle iki diziyi yeni bir diziye birleştir

Swift'in Arraybir reduce(_:_:)yöntemi var. reduce(_:_:)aşağıdaki beyanı içerir :

Belirli bir kapatma kullanarak dizinin öğelerini birleştirmenin sonucunu döndürür.

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

Aşağıdaki Playground kodu, iki tür [Int]dizinin reduce(_:_:)yöntemi kullanarak yeni bir diziye nasıl birleştirileceğini gösterir :

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
Bu kodu paylaştığınız için teşekkürler, iyi açıklama, sadece cevabınıza uyun, hangisinin performansla daha verimli olduğunu söylerseniz en iyisi olur mu?
kokemomuke

Ben +2 diziler ve joined()bir dizi dizi için seviyorum .
Cur

2'den fazla diziyi (veya dizgileri veya başka herhangi bir şeyi) birleştiriyorsanız, yorucuyu +operatörü kullanmaktan koruyun, kesinlikle deli derleme süreleri üretir.
lawicko

@lawicko hangi yöntemi önereceksin?
CyberMew

@CyberMew Aşırı yüklenmiş operatörler kullanmayan herhangi bir şey, yöntem # 3'ü seviyorum çünkü en okunabilir olduğunu düşünüyorum, ancak düz harita ile yöntem # 4'ü de seviyorum. Dizeler için yöntem # 5 seviyorum çünkü sonunda birleştirilmiş dize hemen olsun.
lawicko

34

Büyük bir operatör aşırı yükü hayranı değilseniz veya sadece daha fazla fonksiyonel tipte değilseniz:

// 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'ın düzleşmesinden bu yana en sevdiğim yöntem

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

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

Bu geri dönecek FlattenBidirectionalCollectionEğer bu sadece CollectionTypeyeterli olacak ve ücretsiz tembel değerlendirme olacak bu . Tam olarak Array'a ihtiyacınız varsa bunu yapabilirsiniz:

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

2
flatten()artık var gibi görünmüyor. Ama düşünebilirsiniz joined().
Cur

13

Olası alternatiflerin listesini tamamlamak için reduce, düzleştirme davranışını uygulamak için kullanılabilir :

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

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

Sunulanlar arasında en iyi alternatif (performans / bellek açısından) basitçe flatten , yeni dizileri yeni bir dizi yapısı oluşturmadan tembel bir şekilde sarmaktır.

Ama bildirim olduğunu düzleştirmek dönmez birLazyCollection , böylece tembel davranış zincir boyunca bir sonraki işleme yayılmaz (harita, flatMap, filtre vb.).

Lazyness sizin özel durumda mantıklı varsa, sadece sona ekleme hatırlamak veya eklemek .lazyiçin flatten()Tomasz numuneyi bu şekilde değiştirerek, örneğin,:

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

Bu cevap 2019'da hala Swift 5.1 ile ne kadar iyi duruyor?
willbattel

flatten () artık mevcut değil.
join

4

İkinci dizinin belirli bir dizinden sonra eklenmesini istiyorsanız bunu yapabilirsiniz (Swift 2.2'den itibaren):

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

Swift 3.0

Toplama operatörü ( +) ile uyumlu türlerle iki mevcut diziyi bir araya getirerek yeni bir dizi oluşturabilirsiniz . Yeni dizinin türü, birlikte eklediğiniz iki dizinin türünden çıkarılır,

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]

bu yukarıdaki kodların doğru sonuçlarıdır.


4
var arrayOne = [1,2,3]
var arrayTwo = [4,5,6]

sonuç olarak isterseniz: [1,2,3, [4,5,6]]

arrayOne.append(arrayTwo)

yukarıdaki kod, arrayOne öğesini tek bir öğe olarak dönüştürecek ve arrayTwo öğesinin sonuna ekleyecektir.

sonuç olarak isterseniz: [1, 2, 3, 4, 5, 6] o zaman,

arrayOne.append(contentsOf: arrayTwo)

Yukarıdaki kod, arrayTwo öğesinin sonuna arrayOne öğesinin tüm öğelerini ekler.

Teşekkürler.


4

Swift 4.X

en kolay yolu sadece + işaretini kullanmaktır

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

var Array3 = Array1 + Array2

// Array 3 will just be them combined :)

3

İşte iki diziyi birleştirmenin en kısa yolu.

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

Bunları birleştirin / birleştirin

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

1

Benzer şekilde, dizilerin sözlükleriyle:

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

ve dict1 üzerinde yineleme yapabilir ve "anahtar" eşleşirse dict2'yi ekleyebilirsiniz


0

Farklı veri türleri olan marge dizisi:

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

Çıktı :

["a", true, 3, "b", "hi", 3, [6]]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.