配列を正確に複製するにはどうすればよいですか?
Swiftでのアレイの複製に関する情報を見つけるのに苦労しています。
使ってみた .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
配列を正確に複製するにはどうすればよいですか?
Swiftでのアレイの複製に関する情報を見つけるのに苦労しています。
使ってみた .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
回答:
配列はSwiftで完全な値のセマンティクスを持っているので、特別なことをする必要はありません。
var duplicateArray = originalArray
は、あなたが必要とすることすべてです。
配列の内容が参照型である場合、はい、これはオブジェクトへのポインターのみをコピーします。コンテンツのディープコピーを実行するには、代わりmap
に各インスタンスのコピーを使用して実行します。NSCopying
プロトコルに準拠するFoundationクラスの場合、copy()
メソッドを使用できます。
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
Swiftの値のセマンティクスがユーザーを保護するために機能している落とし穴があることに注意してください。たとえば、NSArray
不変の配列を表すため、そのcopy
メソッドはそれ自体への参照を返すだけなので、上記のテストでは予期しない結果が生じます。
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
を使って遊び場でこれを試し、この出力を得ました:0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
コピーされているように見えません、なぜですか?
x[0] == x[1]
しかしx[0] === y[0]
失敗するはずです
ネイトは正しいです。プリミティブ配列を使用している場合は、元の配列にduplicateArrayを割り当てるだけです。
完全を期すために、NSArrayオブジェクトを使用している場合は、次のようにしてNSArrayの完全なコピーを作成します。
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
ネイトの答えには3つ目の選択肢があります:
let z = x.map { $0 } // different array with same objects
* EDITED *編集はここから始まります
上記は基本的に以下と同じですが、配列が変更されない限りこれはコピーされないため(これは仕様による)、実際には以下の等価演算子を使用するとパフォーマンスが向上します。
let z = x
詳細はこちら:https : //developer.apple.com/swift/blog/?id=10
*編集済み*編集はここで終了します
この配列に追加または削除しても、元の配列には影響しません。ただし、配列が保持するオブジェクトのプロパティを変更すると、元の配列に表示されます。配列内のオブジェクトはコピーではないため(配列がプリミティブ番号ではなくオブジェクトを保持していると仮定)
var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
NSCopying
:、その配列複製let z = x.map { $0.copy as! ClassX }
通常のオブジェクトの場合、実行できることは、コピーをサポートするプロトコルを実装し、オブジェクトクラスにこのプロトコルを次のように実装させることです。
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
そして、クローン用のArray拡張機能:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
コードとサンプルを表示するには、この要点を確認してください
object's
init関数のパラメーターを渡す不必要な煩わしさを回避
クラスオブジェクトの配列のアイテムをコピーしたい場合。次に、NSCopyingプロトコルを使用せずに以下のコードを実行できますが、オブジェクトに必要なすべてのパラメーターを取得するinitメソッドが必要です。遊び場でテストする例のコードは次のとおりです。
class ABC {
var a = 0
func myCopy() -> ABC {
return ABC(value: self.a)
}
init(value: Int) {
self.a = value
}
}
var arrayA: [ABC] = [ABC(value: 1)]
var arrayB: [ABC] = arrayA.map { $0.myCopy() }
arrayB.first?.a = 2
print(arrayA.first?.a)//Prints 1
print(arrayB.first?.a)//Prints 2
var duplicateArray = originalArray