Any idea how can i shuffle randomly for RLMResults
? I couldn't find anyway to do it via RLMSortDescriptor
.
I tried writing my own swap algorithm, but it's giving me error (cannot assign to results of this expression*).
func simpleRandomSwap(rlmobjects:RLMResults!) -> RLMResults! {
if (rlmobjects != nil && rlmobjects.count > 0) {
let indexcount = Int(rlmobjects.count)
for (var i=0 ; i<indexcount; i++) {
let randomUInt:UInt = UInt(arc4random_uniform(UInt32(indexcount)))
let myuint = UInt(i)
// simple swap
var temp = rlmobjects.objectAtIndex(myuint)
rlmobjects.objectAtIndex(randomUInt) = rlmobjects.objectAtIndex(myuint)
rlmobjects.objectAtIndex(myuint) = temp
} // end for loop
}
return rlmobjects
}
First a quick note: RLMResults
have no defined order unless they are sorted via RLMSortDescriptor
.
Instead, to randomly sort you have two options:
Add a integer property to your object schema and assign random values to all the objects. You can then use a RLMSortDescriptor
with RLMResults
to sort the objects.
As mentioned in the comments above, copy the RLMObjects
into an array and perform a random sort on this.
Here is an extension to RLMObject
that does this:
extension RLMResults {
public func toShuffledArray<T>(ofType: T.Type) -> [T] {
var array = [T]()
for result in self {
if let result = result as? T {
array.append(result)
}
}
let count = array.count
if count > 1 {
for i in 0..<(count - 1) {
let j = Int(arc4random_uniform(UInt32(count - i))) + Int(i)
swap(&array[i], &array[j])
}
}
return array
}
}
You would call it like this:
let shuffled = results.toShuffledArray(TestObject.self)