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를 반환하지 않습니까?
thesummersign

2
@thesummersign Realm은 최근 많이 바뀌었지만 한 가지 확실합니다. 위 코드 Array는 결과 반복자로 구성된 Swift를 반환 합니다.
Mazyod

4
그것은 엔티티의 초기 변수를 반환합니다 (초기)
Nik Kov

2
나는 @NikKov에 동의합니다. 그것은 엔티티의 어떤 종류도 반환하지 않는 것 같습니다; (
Jon

2
@ 존 어떻게 그들이 아닌 것을보고 있습니까? 그것들이 게으른 것처럼 보이므로 디버그 지점에서 멈추었을 때 비어있는 것처럼 보이지만 인쇄하면 액세스하고 올바른 값을 보여줍니다 (나를 위해).
예레미야

31

당신이 절대적으로 변환해야하는 경우 ResultsArray, 염두에 두어야하기 때문에, 성능 및 메모리 오버 헤드가있다 Results게으른입니다. 그러나 results.map { $0 }swift 2.0 (또는 map(results) { $0 }1.2) 과 같이 한 줄로 할 수 있습니다 .


어떤 버전의 Realm?
Sahil Kapoor

31
Realm에 대한 종속성을 프로젝트의 너무 많은 클래스에 누설하지 않으려면이 변환이 필요하지 않습니까?
Marcin Kuptel

15
map { $0 }LazyMapRandomAccessCollectionSwift 3에서 반환 되므로 @Mazyod 답변이 더 좋습니다.
Legoless

@MarcinKuptel 예, 정확히 내가 찾은 문제입니다. 프로토콜에 맞는 구조체를 만들어서 영역 모델을 추상화 할 수 있었으며 코드베이스의 서명에서 정의한 프로토콜 추상화입니다. 그러나 때로는 배열로 변환해야합니다. 액세스 할 때 구조체로만 변환되도록 추상화 된 프로토콜의 게으른 컬렉션을 가질 수있는 방법이 있습니까?
Pavan

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
위의 확장명을 작성하는 것은 매우 혼란스러운 방법입니다 : extension Results {var array : [Element] {return self.map {$ 0}}}
Giles

10

Swift 4.2를 사용하면 확장만큼 간단합니다.

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

필요한 모든 제네릭 정보는 이미 Results우리가 확장 한 일부입니다 .


8

이것은 한 줄로 Swift 3Results 확장을 사용하여 Array로 변환하는 또 다른 방법입니다 .

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

대한 스위프트 4 와 엑스 코드 9.2

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

엑스 코드 (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 }
}

그러나 더 좋은 방법은 필요할 때마다 결과를 전달하는 것입니다. 또한 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으로 업데이트 한 후 List는 인수를 사용하지 않습니다. 이 경우 배열을 List로 변환하는 방법은 무엇입니까? 어떤 생각?
Nishu_Priya

1
@NishuPriya 여기에 myList = List <Person> () myList.append (objectsIn : realm.objects (Person.self))
Nosov 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

네. 나도 그렇게 할 것입니다.
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)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.