RealmSwift: Ubah Hasil menjadi Swift Array


143

Apa yang ingin saya terapkan:

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

    return objects.count > 0 ? objects : nil
}

Bagaimana saya bisa mengembalikan objek seolah- [SomeObject]olah jika Results?

Jawaban:


379

Aneh, jawabannya sangat lurus ke depan. Inilah cara saya melakukannya:

let array = Array(results) // la fin

bukankah itu mengembalikan NSArray?
Musim panas

2
@thesummersign Realm telah banyak berubah baru-baru ini, tetapi satu hal yang pasti: Kode di atas mengembalikan Swift yang Arraydibangun dengan hasil iterator.
Mazyod

4
Ini mengembalikan nol entitas (awal)
Nik Kov

2
Saya setuju dengan @NikKov, tampaknya akan mengembalikan nol entitas; (
Jon

2
@ Jon Bagaimana Anda melihat bahwa mereka nihil? Sepertinya karena mereka malas, ketika Anda melihat mereka berhenti pada titik debug mereka tampak kosong tetapi jika Anda mencetaknya itu mengaksesnya dan menunjukkan nilai yang benar (untuk saya).
Yeremia

31

Jika Anda benar-benar harus mengonversi Resultske Array, ingat ada kinerja dan memori overhead, karena Resultsmalas. Tetapi Anda bisa melakukannya dalam satu baris, seperti results.map { $0 }pada swift 2.0 (atau map(results) { $0 }1.2).


Versi Realm yang mana?
Sahil Kapoor

31
Bukankah konversi ini suatu keharusan jika Anda tidak ingin membocorkan ketergantungan pada Realm ke terlalu banyak kelas dalam proyek Anda?
Marcin Kuptel

15
map { $0 }akan kembali LazyMapRandomAccessCollectiondalam Swift 3, jadi jawaban @Mazyod lebih baik.
Legoless

@ Marscinupuptel ya itulah masalah yang saya temukan. Saya sudah bisa mengabstraksi model ranah dengan membuat struct yang sesuai dengan protokol, dan abstraksi protokol inilah yang saya definisikan dalam tanda tangan saya di basis kode saya. Namun kadang-kadang saya perlu mengkonversi ke array, apakah ada cara saya dapat memiliki koleksi malas protokol abstrak saya sehingga hanya mengkonversi ke struct pada waktu akses?
Pavan

20

Saya menemukan solusinya. Ekstensi dibuat pada Hasil.

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

dan menggunakan like

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++ harus diganti denganfor i in 0 ..< count
Sal

1
Cara di atas sangat membingungkan dalam menulis ekstensi: ekstensi Hasil {var array: [Elemen] {return self.map {$ 0}}}
Giles

10

Dengan Swift 4.2, sesederhana ekstensi:

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

Semua informasi generik yang diperlukan sudah menjadi bagian dari Resultsyang kami sampaikan.


8

Ini cara lain untuk mengkonversi Resultsmenjadi Array dengan ekstensi dengan Swift 3 dalam satu baris.

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

Untuk Swift 4 dan Xcode 9.2

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

Dengan Xcode 10 flatMap sudah usang Anda dapat menggunakan compactMapuntuk pemetaan.

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

Saat saya menggunakan kode ini dalam versi 9.2 dari XCode, kode ini menunjukkan saya Penggunaan tipe 'T' yang tidak dideklarasikan
Bhavesh Dhaduk

Diperbarui jawaban saya, Anda dapat memeriksanya.
abdullahselek

Untuk Xcode 10 ke atas, Anda dapat menggunakan compactMap alih-alih flatMap untuk menghindari peringatan.
Metodij Zdravkin

6

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

Pemakaian

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
}

Alternatif: Menggunakan obat generik

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

itu bukan ide yang baik untuk mengonversi Hasil ke Array, karena Hasil malas. Tetapi jika Anda perlu mencoba ini:

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

tetapi cara yang lebih baik adalah memberikan Hasil di mana pun Anda butuhkan. Anda juga dapat mengonversi Hasil ke Daftar alih-alih Array.

List(realm.objects(class))

jika fungsi pertama tidak berfungsi, Anda dapat mencoba yang ini:

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

Setelah memperbarui RealmSwift ke 3.4.0, Daftar tidak mengambil argumen. Bagaimana cara mengubah array ke Daftar dalam kasus ini? Ada ide?
Nishu_Priya

1
@NishuPriya di sini Anda membiarkan myList = Daftar <Person> () myList.append (objekIn: realm.objects (Person.self))
Nosov Pavel

2

Saya tidak yakin, apakah ada cara efisien untuk melakukan ini.

Tetapi Anda bisa melakukannya dengan membuat array Swift dan menambahkannya dalam loop.

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

Jika Anda merasa itu terlalu lambat. Saya sarankan Anda untuk membagikan Resultsobjek Realm secara langsung.


Saya melakukan sesuatu seperti itu hanya dengan membuat ekstensi di Resules sebagai gantinya. Saya telah memposting kode sebagai jawaban. Terima kasih :)
Sahil Kapoor

ya. Saya akan melakukannya juga.
nRewik

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

Jadi, Anda bisa menggunakan like:

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

2

Solusi untuk Swift 4, Realm 3

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

Sekarang konversi dapat dilakukan seperti di bawah ini

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

2
extension Results {
    func materialize() -> [Element] {
        return Array(self)
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.