web-dev-qa-db-ja.com

配列の正確な複製コピーを作成するにはどうすればよいですか?

配列の正確な複製を作成するにはどうすればよいですか?

Swiftでの配列の複製に関する情報を見つけるのに苦労しています。

.copy()を使用してみました

var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
80
Patrick

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メソッドはそれ自体への参照を返すだけなので、上記のテストは予期しない結果をもたらします。

150
Nate Cook

ネイトは正しいです。プリミティブ配列を使用している場合は、duplicateArrayをoriginalArrayに割り当てるだけです。

完全を期すために、NSArrayオブジェクトを操作している場合は、次の手順を実行してNSArrayの完全なコピーを作成します。

var originalArray = [1, 2, 3, 4] as NSArray

var duplicateArray = NSArray(array:originalArray, copyItems: true)
26
applejack42

Nateの答えには3番目のオプションがあります。

let z = x.map { $0 }  // different array with same objects

*編集済み*編集はここから始まります

上記は基本的に以下と同じであり、実際に以下の等値演算子を使用すると、変更しない限り配列がコピーされないため、パフォーマンスが向上します(これは仕様によるものです)。

let z = x

詳細はこちら: https://developer.Apple.com/Swift/blog/?id=1

*編集済み*編集はここで終了

この配列に追加または削除しても、元の配列には影響しません。ただし、配列が保持するオブジェクトのプロパティを変更すると、元の配列に表示されます。配列内のオブジェクトはコピーではないため(配列がプリミティブ番号ではなくオブジェクトを保持していると仮定)。

15
oyalhi

通常のオブジェクトに対してできることは、コピーをサポートするプロトコルを実装し、オブジェクトクラスに次のようにこのプロトコルを実装させることです。

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
    }
}

コードとサンプルを表示するには、これを確認してください Gist

13
Sohayb Hassoun