RealmSwift:結果をSwift配列に変換


143

実装したいもの:

class func getSomeObject() -> [SomeObject]? {
    let objects = Realm().objects(SomeObject)

    return objects.count > 0 ? objects : nil
}

どう[SomeObject]すれば代わりにオブジェクトを返すことができResultsますか?

回答:


379

奇妙なことに、答えは非常に簡単です。ここに私がそれをする方法があります:

let array = Array(results) // la fin

NSArrayを返しませんか?
thesummersign 2015年

2
@thesummersign Realmは最近大きく変更されていますが、確かなことが1つありArrayます。上記のコードは、結果イテレーターで構成されたSwiftを返します。
Mazyod 2015年

4
エンティティのnil varsを返します(初期)
Nik Kov

2
私は@NikKovに同意します、それはエンティティのnil varsを返すようです;(
Jon

2
@ジョン彼らが無事だとどう思いますか?彼らは怠惰なので、デバッグポイントで停止したときにそれらが空に見えますが、それらを印刷すると、それらにアクセスして正しい値を表示します(私にとって)。
エレミヤ

31

を絶対にに変換する必要がある場合は、遅延が発生するため、パフォーマンスとメモリのオーバーヘッドが発生するResultsことArrayに注意してくださいResults。しかしresults.map { $0 }、Swift 2.0(またはmap(results) { $0 }1.2)のように、1行で実行できます。


レルムのどのバージョンですか?
Sahil Kapoor 2015

31
Realmへの依存関係をプロジェクトのあまりにも多くのクラスに漏らしたくない場合、この変換は必要ではありませんか?
Marcin Kuptel、2015年

15
map { $0 }LazyMapRandomAccessCollectionSwift 3で返されるので、@ Mazyodの回答の方が優れています。
Legoless 2016

@MarcinKuptelはい、それはまさに私が見つけた問題です。プロトコルに準拠した構造体を作成することで、レルムモデルを抽象化することができました。コードベースのシグネチャで定義するのは、このプロトコルの抽象化です。ただし、配列に変換する必要がある場合がありますが、アクセス時に構造体にのみ変換されるように、抽象化されたプロトコルの遅延コレクションを取得できる方法はありますか?
Pavan 2018

20

解決策を見つけました。結果に拡張機能を作成しました。

extension Results {
    func toArray<T>(ofType: T.Type) -> [T] {
        var array = [T]()
        for i in 0 ..< count {
            if let result = self[i] as? T {
                array.append(result)
            }
        }

        return array
    }
}

と同様に使用

class func getSomeObject() -> [SomeObject]? {
    let objects = Realm().objects(SomeObject).toArray(SomeObject) as [SomeObject]

    return objects.count > 0 ? objects : nil
}

4
for var i = 0; i < count; i++ 次のものと置き換える必要がありますfor i in 0 ..< count
Sal

1
上記は、拡張機能を記述する非常に混乱する方法です:拡張結果{var array:[Element] {return self.map {$ 0}}}
Giles

10

Swift 4.2では、拡張機能と同じくらい簡単です。

extension Results {
    func toArray() -> [Element] {
      return compactMap {
        $0
      }
    }
 }

必要なジェネリック情報はすべて、すでにResults拡張の一部です。


8

これは、1行ResultsSwift 3を使用して拡張子を付けた配列に変換する別の方法です。

extension Results {
    func toArray() -> [T] {
        return self.map { $0 }
    }
}

スイフト4とXcode 9.2

extension Results {
    func toArray<T>(type: T.Type) -> [T] {
        return flatMap { $0 as? T }
    }
}

ではXcodeの10 flatMapあなたが使用できる推奨されていませんcompactMapマッピングのために。

extension Results {
    func toArray<T>(type: T.Type) -> [T] {
        return compactMap { $0 as? T }
    }
}

XCodeの9.2バージョンでこのコードを使用しているため、宣言されていない型 'T'の使用が示されています
Bhavesh Dhaduk

私の答えを更新しました、あなたはそれをチェックすることができます。
abdullahselek

Xcode 10以降では、警告を回避するために、flatMapの代わりにcompactMapを使用できます。
Metodij Zdravkin

6

スウィフト3

extension Results {
    func toArray<T>(ofType: T.Type) -> [T] {
        var array = [T]()
        for i in 0 ..< count {
            if let result = self[i] as? T {
                array.append(result)
            }
        }

        return array
    }
}

使用法

class func getSomeObject() -> [SomeObject]? {
   let defaultRealm = try! Realm()
    let objects = defaultRealm.objects(SomeObject.self).toArray(ofType : SomeObject.self) as [SomeObject]

    return objects.count > 0 ? objects : nil
}

代替:ジェネリックの使用

class func getSomeObject() -> [T]? {
        let objects = Realm().objects(T.self as! Object.Type).toArray(ofType : T.self) as [T]

        return objects.count > 0 ? objects : nil
}

4

結果は遅延するため、結果を配列に変換することはお勧めできません。しかし、これを試す必要がある場合:

func toArray<T>(ofType: T.Type) -> [T] {
    return flatMap { $0 as? T }
}

しかし、より良い方法は、必要な場所に結果を渡すことです。また、結果を配列の代わりにリストに変換することもできます。

List(realm.objects(class))

最初の関数が機能しない場合は、次の関数を試すことができます。

var refrenceBook:[RefrenceProtocol] = []
let faceTypes = Array(realm.objects(FaceType))
refrenceBook = faceTypes.map({$0 as FaceType})

RealmSwiftを3.​​4.0に更新した後、Listは引数を取りません。この場合、配列をリストに変換するにはどうすればよいですか?何か案が?
Nishu_Priya

1
@NishuPriyaここでは、myList = List <Person>()myList.append(objectsIn:realm.objects(Person.self))
Pavel

2

これを行う効率的な方法があるかどうかはわかりません。

しかし、Swift配列を作成してループに追加することでそれを行うことができます。

class func getSomeObject() -> [SomeObject]? {
    var someObjects: [SomeObject] = []
    let objects = Realm().objects(SomeObject)
    for object in objects{
        someObjects += [object]
    }
    return objects.count > 0 ? someObjects : nil
}

遅すぎると感じた場合。Realm Resultsオブジェクトを直接渡すことをお勧めします。


代わりにResulesに拡張機能を作成するだけで、そのようなことを行いました。コードを回答として投稿しました。ありがとう:)
Sahil Kapoor 2015年

ええ。私もそうします。
nRewik 2015年

2
extension Results {
    var array: [Element]? {
        return self.count > 0 ? self.map { $0 } : nil
    }
}

したがって、次のように使用できます。

Realm().objects(SomeClass.self).filter("someKey ENDSWITH %@", "sth").array

2

Swift 4、Realm 3のソリューション

extension Results {
    func toArray<T>(ofType: T.Type) -> [T] {
        let array = Array(self) as! [T]
        return array
    }
}

今変換は以下のように行うことができます

let array = Realm().objects(SomeClass).toArray(ofType: SomeClass.self)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.