Is it possible to store multi dimensional data array in realm?


#1

I have a matrix (array of arrays of type int) I wish to store in realm.
Is it possibel ? if so how do I define the data type ?

example :

[
[787,1280],[886,1411],[951,1493],[1017,1591],[1083,1690],[1148,1788],[1214,1903],[1247,1969],
[886,1411],[984,1558],[1066,1657],[1132,1772],[1214,1870],[1296,1985],[1378,2133],[1444,2231],
[984,1558],[1099,1722],[1181,1837],[1280,1968],[1363,2100],[1476,2247],[1575,2411],[1640,2526],
[1099,1722],[1230,1903],[1329,2051],[1444,2215],[1575,2379],[1690,2559],[1837,2756],[1919,2887],
[1230,1903],[1394,2149],[1526,2329],[1657,2510],[1804,2707],[1968,2920],[2100,3133],[2198,3281]
]


#2

I know this is a Realm React question but let me pose a couple of options using some Swift code.

You ‘can’t’ store nested arrays directly in Realm as presented - only primatives. However, realm does support a more generic Data (NSData in objc) type. So you can encode your matrix into a Data type and store that.

Something along these lines should get you going:

let data = try NSKeyedArchiver.archivedData(withRootObject: myArray, requiringSecureCoding: false)

and then when reading it back

if let thisArray = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)

Another option, is to simply create an object to hold your datasets and then store those within another object List property. Here’s an example: suppose we want to store a list of location coordinates within a State. Here’s a location object to be persisted in Realm

class LocationClass: Object {
    @objc dynamic var latitude = ""
    @objc dynamic var longitude = ""
    
    convenience init(lat: String, lon: String) {
        self.init()
        self.latitude = lat
        self.longitude = lon
    }
}

and then a State object to hold the locations within that state

class StateClass: Object {
    @objc dynamic var which_state = ""
    let locations = List<LocationClass>()
    
    //an alternative to get an actual matrix as described in the question 
    func getMultiArray() -> [ [String] ] {
        var outerArray = [ [String] ]()
        for loc in locations {
            var array = [String]()
            array.append(loc.latitude)
            array.append(loc.longitude)
            outerArray.append(array)
        }
        
        return outerArray
    }
}

and then finally the code to create the objects and store them within Realm

        let loc0 = LocationClass(lat: "787", lon: "1280")
        let loc1 = LocationClass(lat: "866", lon: "1411")
        let loc2 = LocationClass(lat: "951", lon: "1493")
        
        let state = StateClass()
        state.which_state = "Florida"
        state.locations.append(loc0)
        state.locations.append(loc1)
        state.locations.append(loc2)
        
        if let realm = gGetRealm() {
            try! realm.write {
                realm.add(state)
            }
        }

Then, to test, we can either iterate over the stored locations OR if you want it back an an array as presented in the question, call the getMultiArray function

    if let realm = gGetRealm() {
        let results = realm.objects(StateClass.self)
        guard let aState = results.first else {return}
        
        for location in aState.locations {
            let lat = location.latitude
            let long = location.longitude
            print(lat, long)
        }
        
        let test = aState.getMultiArray()
        print(test)
    }

and the output

787 1280
866 1411
951 1493
[["787", "1280"], ["866", "1411"], ["951", "1493"]]

#3

Thank you Jay for the detailed answer !

Happy 2019

Yuval