LoginSignup
8
2

More than 5 years have passed since last update.

【Swift4】まだ、そんなだせえ方法でArray初期化してるの?

Last updated at Posted at 2018-08-25

Swiftでテストデータなどを作成する時に、Arrayに同じ値を複数個入れて初期化したい時があります。

そういう時に、つい、こういうやり方をしてしまいがちです。

// 直書きで入れる
var array = [0,0,0,0,0]
// クロージャーでfor文を使う
var array: [Int] = {
    var array = [Int]()
    for _ in 0 ..< 5 {
        array.append(0)
    }
    return array
}()

もっと便利に書く方法

SwiftのArrayには、以下のようなイニシャライズがあります。

public init(repeating repeatedValue: Array.Element, count: Int)

これは、repeatedValueに渡された値を、countの数だけ格納して初期化してくれるので、最初にあげたようなやり方を、スマートに書くことができます。

var array = [Int](repeating: 0, count: 5)

注意点

classオブジェクトをrepeatedValueに指定した場合、参照を複製してしまうため、Arrayの中身の値を書き換えた時に、初期化時の値全てに反映されてしまうので注意が必要です。

class TestClass {
    var value = 0
}

var array = [TestClass](repeating: TestClass(), count: 5)
// 0番目を書き換えてログに出力する。
array[0].value = 100
array.forEach { print($0.value) }

// 0番目以外も変わってしまう!
/*
 出力結果
 100
 100
 100
 100
 100
 */

もちろんstructなどの値渡しオブジェクトを使用する際は、この注意点を気にする必要はありません。

struct TestStruct {
    var value = 0
}

var array = [TestStruct](repeating: TestStruct(), count: 5)
array[0].value = 100
array.forEach { print($0.value) }

// 0番目だけが変わる!
/*
 出力結果
 100
 0
 0
 0
 0
 */

おまけ

Extension

どうしてもクラスでやりたいけれど、参照が複製されたら困る場合に使うArrayのExtensionです。

extension Array {

    init(count: Int, repeating closure: () -> Element) {
        var array = [Element]()
        for _ in 0 ..< count {
            array.append(closure())
        }
        self = array
    }
}

使い方

var array = [TestClass](count: 5) { TestClass() }
array[0].value = 100
array.forEach { print($0.value) }

// 0番目だけが変わる!
/*
 出力結果
 100
 0
 0
 0
 0
 */
8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2