RealmSwift: Sonuçları Swift Array'a Dönüştür


143

Ne uygulamak istiyorum:

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

    return objects.count > 0 ? objects : nil
}

[SomeObject]Bunun yerine nesneyi nasıl döndürebilirim Results?

Yanıtlar:


379

Garip, cevap çok basit. İşte nasıl yaparım:

let array = Array(results) // la fin

bir NSArray döndürmüyor mu?
thesummersign

2
@ thesummersign Realm son zamanlarda çok değişiyor, ancak kesin olan bir şey var: Yukarıdaki kod Array, sonuç yineleyici ile oluşturulmuş bir Swift döndürür .
Mazyod

4
Varlığın sıfır çeşitliliğini verir (başlangıç)
Nik Kov

2
@NikKov ile hemfikirim, varlığın nil çeşitlerini iade ediyor gibi görünüyor; (
Jon

2
@Jon Nil olduklarını nasıl görüyorsun? Tembel oldukları için, bir hata ayıklama noktasında durduklarına baktığınızda boş görünürler, ancak yazdırırsanız, onlara erişir ve doğru değeri gösterir (benim için).
Yeremya

31

Kesinlikle senin dönüştürmek gerekir Resultsiçin Array, akılda tutulması beri, bir performans ve bellek havai var Resultstembeldir. Ancak bunu results.map { $0 }hızlı 2.0'da (veya map(results) { $0 }1.2'de) olduğu gibi tek bir satırda yapabilirsiniz .


Hangi Diyar sürümü?
Sahil Kapoor

31
Projenizde çok fazla sınıfa Diyar'a bağımlılık istemiyorsanız bu dönüşüm bir gereklilik değil mi?
Marcin Kuptel

15
map { $0 }LazyMapRandomAccessCollectionSwift 3'te geri dönecek , bu yüzden @Mazyod cevabı daha iyi.
Legoless

@MarcinKuptel evet bulduğum problem tam olarak bu. Bir protokole uygun bir yapı oluşturarak bölge modelini soyutlayabildim ve kod tabanımdaki imzalarımda tanımladığım bu protokol soyutlaması. Ancak bazen bir diziye dönüştürmek gerekiyor, bu yüzden sadece erişim zamanında yapı dönüştürür benim soyutlanmış protokol tembel bir koleksiyon olabilir yolu var mı?
Pavan

20

Bir çözüm buldum. Sonuçlar üzerinde uzantı oluşturuldu.

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

ve gibi kullanmak

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++ ile değiştirilmelidirfor i in 0 ..< count
Sal

1
Yukarıdakiler, uzantıyı yazmanın çok kafa karıştırıcı bir yoludur: extension Results {var array: [Element] {return self.map {$ 0}}}
Giles

10

Swift 4.2 ile bir uzantı kadar basit:

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

Gerekli tüm jenerik bilgiler zaten bir kısmını Resultsgenişlettiğimiz bir bölümdür .


8

Bu Results, Swift 3 ile tek bir satırda bir uzantıyla Array'a dönüştürmenin başka bir yoludur .

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

İçin Swift 4 ve Xcode 9.2

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

İle Xcode 10 flatMap kullanımdan kaldırıldı kullanabileceğiniz compactMapharitalama.

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

Bu kodu
XCode'un

Cevabımı güncelledim, kontrol edebilirsiniz.
abdullahselek

Xcode 10 ve üstü sürümlerde uyarıyı önlemek için flatMap yerine compactMap kullanabilirsiniz.
Metodij Zdravkin

6

Hızlı 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
    }
}

kullanım

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: Jenerik kullanımı

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

Sonuçları Diziye dönüştürmek iyi bir fikir değildir, çünkü Sonuçlar tembeldir. Ancak ihtiyacınız varsa bunu deneyin:

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

ancak daha iyi bir yol, sonuçları ihtiyacınız olan yere iletmektir. Ayrıca Sonuçları Array yerine Listeye dönüştürebilirsiniz.

List(realm.objects(class))

ilk işlev çalışmıyorsa, bunu deneyebilirsiniz:

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

RealmSwift'i 3.4.0 olarak güncelledikten sonra List argüman almaz. Bu durumda bir diziyi Liste'ye nasıl dönüştürebilirim? Herhangi bir fikir?
Nishu_Priya

1
@NishuPriya burada myList = Liste <Person> () myList.append (objectsIn: realm.objects (Person.self))
Nosov Pavel

2

Bunu yapmanın etkili bir yolu olup olmadığından emin değilim.

Ancak bunu bir Swift dizisi oluşturarak ve döngüye ekleyerek yapabilirsiniz.

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

Çok yavaş olduğunu düşünüyorsanız. ResultsDoğrudan Realm nesnesinin etrafından geçmenizi öneririm .


Bunun yerine sadece Resules üzerinde bir uzantı oluşturarak böyle bir şey yaptım. Kodu cevap olarak gönderdim. Teşekkürler :)
Sahil Kapoor

Evet. Bunu ben de yaparım.
nRewik

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

Yani, şöyle kullanabilirsiniz:

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

2

Çözüm Swift 4, Diyar 3

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

Şimdi dönüştürme aşağıdaki gibi yapılabilir

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

2
extension Results {
    func materialize() -> [Element] {
        return Array(self)
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.