文書   >   Swift   >   Array


汎用構造体


Array


順序付けられた、ランダムアクセスコレクション。





宣言


struct Array<Element>


概観


配列 (Arrays) は、アプリで最も一般的に使用されるデータ型の 1 つです。アプリのデータを整理するために配列を使用して下さい。具体的には、Array 型を使用して、単一の型の要素、つまり配列の Element 型を保持して下さい。配列には、整数から文字列、クラスまで、あらゆる種類の要素を格納できます。


Swift を使用すると、配列リテラルを使用してコード内に配列を簡単に作成できます。値のカンマ区切りリストを角括弧で囲むだけです。他に情報がなければ、Swift は指定された値を含む配列を作成し、自動的に配列の Element 型を推測します。例えば:


// An array of 'Int' elements
let oddNumbers = [1, 3, 5, 7, 9, 11, 13, 15]

// An array of 'String' elements
let streets = ["Albemarle", "Brandywine", "Chesapeake"]


宣言に配列の Element 型を指定することで、空の配列を作成できます。例えば:


// Shortened forms are preferred
var emptyDoubles: [Double] = []

// The full type name is also allowed
var emptyFloats: Array<Float> = Array()


固定した数のデフォルト値で事前に初期化されている配列が必要な場合は、Array(repetition:count:) イニシャライザを使用してください。


var digitCounts = Array(repeating: 0, count: 10)
print(digitCounts)
// Prints "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"


配列の値にアクセス


配列のすべての要素に対して操作を実行する必要がある場合は、for-in ループを使用して配列の内容を繰り返し処理します。


for street in streets {
    print("I don't live on \(street).")
}
// Prints "I don't live on Albemarle."
// Prints "I don't live on Brandywine."
// Prints "I don't live on Chesapeake."


isEmpty プロパティを使用して配列に要素があるかどうかをすばやく確認するか、count プロパティを使用して配列内の要素数を見つけます。


if oddNumbers.isEmpty {
    print("I don't know any odd numbers.")
} else {
    print("I know \(oddNumbers.count) odd numbers.")
}
// Prints "I know 8 odd numbers."


配列の最初の要素と最後の要素の値に安全にアクセスするには、first プロパティと last プロパティを使用します。配列が空の場合、これらのプロパティは nil です。


if let firstElement = oddNumbers.first, let lastElement = oddNumbers.last {
    print(firstElement, lastElement, separator: ", ")
}
// Prints "1, 15"

print(emptyDoubles.first, emptyDoubles.last, separator: ", ")
// Prints "nil, nil"


サブスクリプトを使って個々の配列要素にアクセスできます。空でない配列の最初の要素は常にインデックスゼロです。配列には、ゼロから配列のカウントまでの、カウントを含めない、任意の整数でサブスクリプトを付けることができます。負の数または count 以上のインデックスを使用すると、実行時エラーが発生します。例えば:


print(oddNumbers[0], oddNumbers[3], separator: ", ")
// Prints "1, 7"

print(emptyDoubles[0])
// Triggers runtime error: Index out of range


要素の追加と削除


あなたが教えているクラスにサインアップしている生徒の名前のリストを保管する必要があるとします。登録期間中は、生徒がクラスを追加および削除したときに名前を追加および削除する必要があります。


var students = ["Ben", "Ivy", "Jordell"]


配列の最後に単一の要素を追加するには、append(_:) メソッドを使用します。append(contentsOf:) メソッドに別の配列または任意の種類のシーケンスを渡して、複数の要素を同時に追加します。


students.append("Maxime")
students.append(contentsOf: ["Shakia", "William"])
// ["Ben", "Ivy", "Jordell", "Maxime", "Shakia", "William"]


単一の要素に対して insert(_:at:) メソッドを使用し、別のコレクションまたは配列リテラルから複数の要素を挿入するためには insert(contentsOf:at:) を使用して、配列の途中に新しい要素を追加できます。そのインデックス以降のインデックスの要素は、スペースを空けるために後ろに移動されます。


students.insert("Liam", at: 3)
// ["Ben", "Ivy", "Jordell", "Liam", "Maxime", "Shakia", "William"]


配列から要素を削除するには、remove(at:)removeSubrange(_:)、および removeLast() メソッドを使用して下さい。


// Ben's family is moving to another state
students.remove(at: 0)
// ["Ivy", "Jordell", "Liam", "Maxime", "Shakia", "William"]

// William is signing up for a different class
students.removeLast()
// ["Ivy", "Jordell", "Liam", "Maxime", "Shakia"]


新しい値をサブスクリプトに割り当てることで、既存の要素を新しい値に置き換えることができます。


if let i = students.firstIndex(of: "Maxime") {
    students[i] = "Max"
}
// ["Ivy", "Jordell", "Liam", "Max", "Shakia"]


配列のサイズを大きくする


すべての配列は、その内容を保持するために特定の量のメモリを予約します。配列に要素を追加し、その配列が予約された容量を超え始めると、配列はより大きなメモリ領域を割り当て、その要素を新しい記憶領域にコピーします。新しい記憶領域は、古い記憶領域のサイズの倍数です。この指数関数的成長戦略は、要素の追加が一定の時間で行われ、多くの追加操作のパフォーマンスが平均化されることを意味します。再割り当てをトリガーする追加操作はパフォーマンス上のコストがかかりますが、配列が大きくなるにつれて発生する頻度は少なくなります。


およそいくつの要素を格納する必要があるかがわかっている場合は、中間の再割り当てを避けるために、配列に追加する前に reserveCapacity(_:) メソッドを使用してください。capacitycount のプロパティを使用して、より大きな記憶域を割り当てずに配列が格納できる要素数を決定します。


ほとんどの Element 型の配列の場合、この記憶領域は連続したメモリのブロックです。Element 型がクラスまたは @objc プロトコル型の配列の場合、この記憶領域は連続したメモリのブロックまたは NSArray のインスタンスになります。NSArray の任意のサブクラスは Array になる可能性があるため、この場合の表現または効率についての保証はありません。


配列のコピーの修正


各々の配列は、そのすべての要素の値を含む独立した値を持ちます。整数や他の構造体などの単純型の場合、これは、1 つの配列内の値を変更しても、その要素の値はその配列のコピー内では変更されないことを意味します。例えば:


var numbers = [1, 2, 3, 4, 5]
var numbersCopy = numbers
numbers[0] = 100
print(numbers)
// Prints "[100, 2, 3, 4, 5]"
print(numbersCopy)
// Prints "[1, 2, 3, 4, 5]"


配列内の要素がクラスのインスタンスである場合、その意味は同じですが、最初は異なるように見えます。この場合、配列に格納されている値は、配列の外部に存在するオブジェクトへの参照です。1 つの配列内のオブジェクトへの参照を変更した場合、その配列だけが新しいオブジェクトへの参照を持ちます。ただし、2 つの配列に同じオブジェクトへの参照が含まれている場合は、両方の配列からそのオブジェクトのプロパティへの変更を確認できます。例えば:


// An integer type with reference semantics
class IntegerReference {
    var value = 10
}
var firstIntegers = [IntegerReference(), IntegerReference()]
var secondIntegers = firstIntegers

// Modifications to an instance are visible from either array
firstIntegers[0].value = 100
print(secondIntegers[0].value)
// Prints "100"

// Replacements, additions, and removals are still visible
// only in the modified array
firstIntegers[0] = IntegerReference()
print(firstIntegers[0].value)
// Prints "10"
print(secondIntegers[0].value)
// Prints "100"


標準ライブラリ内のすべての可変サイズコレクションと同様に、配列は書き込み時コピーの最適化を使用します。いずれかのコピーを変更するまで、配列の複数のコピーが同じ記憶領域を共有します。それが起こると、変更されている配列はその記憶領域をそれ自身の唯一所有されているコピーで置き換え、それはその時その場で変更されます。コピー量を減らすことができる最適化が時々適用されます。


これは、配列が他のコピーと記憶領域を共有している場合、その配列に対する最初の変更操作で配列をコピーするコストが発生することを意味します。その記憶領域の唯一の所有者である配列は、変更操作をその場で実行できます。


以下の例では、同じ記憶領域を共有する 2 つのコピーとともに numbers 配列が作成されます。元の numbers の配列が変更されると、変更を行う前にその記憶領域の唯一のコピーが作成されます。2 つのコピーが元の記憶領域を共有し続けている間、nmubers へのさらなる修正が行われます。


var numbers = [1, 2, 3, 4, 5]
var firstCopy = numbers
var secondCopy = numbers

// The storage for 'numbers' is copied here
numbers[0] = 100
numbers[1] = 200
numbers[2] = 300
// 'numbers' is [100, 200, 300, 4, 5]
// 'firstCopy' and 'secondCopy' are [1, 2, 3, 4, 5]


Array と NSArray 間のブリッジ


Array ではなく NSArray インスタンス内のデータを必要とする API にアクセスする必要がある場合は、型キャスト演算子 (as) を使用してインスタンスをブリッジします。ブリッジを可能にするには、配列の Element 型がクラス、@objc プロトコル (Objective-C からインポートされた、または @objc 属性でマークされたプロトコル)、または Foundation 型にブリッジする型でなければなりません。


以下の例は、write(to:atomically:) メソッドを使用するために、Array インスタンスを NSArray にブリッジする方法を示しています。この例では、colors 配列の String 要素が NSString にブリッジされているため、colors 配列を NSArray にブリッジできます。一方、その Element 型は Optional<String> であり、Foundation 型にはブリッジされないため、コンパイラは moreColors 配列をブリッジするのを防ぎます。


let colors = ["periwinkle", "rose", "moss"]
let moreColors: [String?] = ["ochre", "pine"]

let url = NSURL(fileURLWithPath: "names.plist")
(colors as NSArray).write(to: url, atomically: true)
// true

(moreColors as NSArray).write(to: url, atomically: true)
// error: cannot convert value of type '[String?]' to type 'NSArray'


配列の要素がすでにクラスまたは @objc プロトコルのインスタンスである場合、Array から NSArray へのブリッジには O(1) 時間および O(1) 空間が必要です。そうでなければ、O(n) の時間と空間がかかります。


目的の配列の要素型がクラスまたは @objc プロトコルの場合、NSArray から Array へのブリッジは、まず配列に対して copy(with:) メソッドを呼び出し (Objective-C では - copyWithZone:) 、不変コピーを取得してから追加の O(1) の時間がかかる Swift の簿記作業実行を行います。すでに不変の NSArray のインスタンスの場合、copy(with:) は通常 O(1) 時間内に同じ配列を返します。それ以外の場合、コピーのパフォーマンスは規定されていません。copy(with:) が同じ配列を返す場合、NSArrayArray のインスタンスは、Array の 2 つのインスタンスが記憶領域を共有するときに使用されるのと同じ書き込み時コピーの最適化を使用して記憶領域を共有します。


目的の配列の要素型が Foundation 型にブリッジする非クラス型である場合、NSArray から Array へのブリッジは、O(n) 時間内に連続した記憶領域への要素のコピーのブリッジを実行します。たとえば、NSArray から Array<Int> へのブリッジはそのようなコピーを実行します。Array インスタンスの要素にアクセスするときに、それ以上のブリッジは必要ありません。


注意:

ContiguousArrayArraySlice 型はブリッジされません。これらの型のインスタンスは、常にその記憶領域として連続したメモリのブロックを持っています。


トピックス





配列の作成





配列の検査





要素にアクセス





要素の追加





配列の結合





要素の削除





要素の検索





要素の選択





要素の除外





配列の変換





配列の要素を繰り返し処理





配列の要素を並べ替え





要素の分割と結合





配列の比較





インデックスの操作





基礎となる記憶領域へのアクセス





コード化と復号化





配列 (Array) の記述





関連した配列型





参照型





サポートする型





配列間の変換と ML 型の作成





あまり使用されない機能





イニシャライザ





インスタンスプロパティ





インスタンスメソッド


関連





以下に準拠


以下も見よ





標準ライブラリ

















トップへ












トップへ












トップへ












トップへ












トップへ
目次
Xcode 10 の新機能

  • 言語:Swift
  • SDK
  • Xcode 6.0.1+
  • Framework
  • Swift 標準ライブラリ
  • 宣言
  • 概観
  • トピックス
  • 関連
  • 以下も見よ












  • トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ












    トップへ