RealmSwift: स्विफ्ट ऐरे में परिणाम परिवर्तित करें


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 नहीं लौटाता है?
थिसुमर्सगिन

2
@thesummersign Realm हाल ही में बहुत कुछ बदल रहा है, लेकिन एक बात सुनिश्चित है: ऊपर दिए गए कोड के परिणामस्वरूप स्विफ्ट के Arrayसाथ स्विफ्ट का निर्माण होता है।
माजिद नोव

4
यह इकाई के प्रारंभिक संस्करण (प्रारंभिक)
निक कोव

2
मैं @NikKov से सहमत हूं, ऐसा लगता है कि इकाई के शून्य संस्करण लौट रहे हैं; (
जॉन

2
@Jon आप कैसे देख रहे हैं कि वे शून्य हैं? ऐसा लगता है जैसे वे आलसी हैं, जब आप उन्हें एक डिबग बिंदु पर रोकते हुए देखते हैं तो वे खाली दिखाई देते हैं लेकिन यदि आप उन्हें प्रिंट करते हैं तो यह उन्हें एक्सेस करता है और सही मूल्य दिखाता है (मेरे लिए)।
यिर्मयाह

31

यदि आप बिल्कुल अपने Resultsको परिवर्तित करना चाहते हैं Array, तो ध्यान रखें कि Resultsआलसी होने के बाद भी प्रदर्शन और मेमोरी ओवरहेड है। लेकिन आप इसे एक पंक्ति में कर सकते हैं, जैसे results.map { $0 }कि स्विफ्ट 2.0 (या map(results) { $0 }1.2) में।


दायरे का कौन सा संस्करण?
साहिल कपूर

31
क्या यह रूपांतरण एक आवश्यकता नहीं है यदि आप अपने प्रोजेक्ट में बहुत से वर्गों के लिए दायरे पर निर्भरता को लीक नहीं करना चाहते हैं?
मार्सिन कुप्टेल

15
map { $0 }LazyMapRandomAccessCollectionस्विफ्ट 3 में लौटेंगे , इसलिए @Mazyod का जवाब बेहतर है।
18

@MarcinKuptel हाँ, यही समस्या मुझे मिली। मैं एक संरचना का निर्माण करके दायरे मॉडल को अमूर्त करने में सक्षम हूं जो एक प्रोटोकॉल के अनुरूप है, और यह यह प्रोटोकॉल अमूर्त है जिसे मैं अपने कोडबेस में अपने हस्ताक्षरों में परिभाषित करता हूं। हालांकि कभी-कभी मुझे एक सरणी में बदलने की आवश्यकता होती है, क्या ऐसा कोई तरीका है जिससे मैं अपने अमूर्त प्रोटोकॉल का एक आलसी संग्रह कर सकता हूं ताकि यह केवल एक्सेस समय पर संरचना में परिवर्तित हो जाए?
पावन

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

स्विफ्ट 4.2 के साथ यह विस्तार की तरह सरल है:

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

सभी आवश्यक जेनरिक जानकारी पहले से ही एक हिस्सा है Resultsजिसका हम विस्तार करते हैं।


8

यह एक पंक्ति में स्विफ्ट 3 केResults विस्तार के साथ एरे में परिवर्तित होने का एक और तरीका है ।

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 संस्करण में इस कोड का उपयोग कर रहा हूं, यह मुझे अघोषित प्रकार 'टी' का उपयोग दिखाता है
भावेश धडुक

मेरा उत्तर अपडेट किया गया है, आप इसे देख सकते हैं।
अब्दुल्लाहसेलेक

चेतावनी से बचने के लिए Xcode 10 और इसके बाद के संस्करण के लिए आप flatMap के बजाय CompactMap का उपयोग कर सकते हैं।
मेटोडिज ज़द्रविकिन

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

लेकिन बेहतर तरीका यह है कि आपको जहां भी आवश्यकता हो, परिणाम पारित करें। इसके अलावा आप Array के बजाय Results को List में बदल सकते हैं।

List(realm.objects(class))

अगर पहला फंक काम नहीं कर रहा है तो आप इसे आज़मा सकते हैं:

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

RealmSwift को 3.4.0 में अपडेट करने के बाद, सूची में तर्क नहीं हैं। इस मामले में किसी सरणी को सूची में कैसे बदला जाए? कोई उपाय?
निशु_प्रिया

1
@ निशुप्रिया यहां आपको myList = सूची <व्यक्ति> () myList.append (ऑब्जेक्ट्स: realm.objects (Person.self))
Nosov Pavel

2

मुझे यकीन नहीं है, अगर ऐसा करने के लिए कोई कुशल तरीका है।

लेकिन आप इसे एक स्विफ्ट सरणी बनाकर कर सकते हैं और इसे लूप में जोड़ सकते हैं।

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

अगर आपको लगता है कि यह बहुत धीमा है। मैं आपको Resultsसीधे Realm ऑब्जेक्ट के आसपास से गुजरने की सलाह देता हूं ।


मैंने कुछ ऐसा ही किया, जिसके बदले Resules पर एक एक्सटेंशन बनाया गया। मैंने उत्तर के रूप में कोड पोस्ट किया है। धन्यवाद :)
साहिल कपूर

हाँ। मैं वह भी करूंगा।
nRewik

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

तो, आप का उपयोग कर सकते हैं जैसे:

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

2

स्विफ्ट 4, दायरे 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)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.