Search code examples
c#prime31

How do I access Keys/values of a nested List?


I'm using a unity plugin to handle Facebook called prime[31] Social Networking Plugin. It works fine for something like this:

void onGraph()
    {
        Facebook.instance.graphRequest( "me", HTTPVerb.GET, ( error, obj ) =>
        {
            // if we have an error we dont proceed any further
            if( error != null )
                return;             
            if( obj == null )
                return;             
            // grab the userId and persist it for later use
            var ht = obj as Dictionary<string,object>;
            _userId = ht["id"].ToString();      

            Debug.Log( "me Graph Request finished: " + _userId );
            Prime31.Utils.logObject( ht );
        } );
    }

It returns this:

 --------- IDictionary ---------
id: ########## 
name: Mike O'Connor 
first_name: Mike 
last_name: O'Connor 
link: https://www.facebook.com/########## 
username: ########## 
etc...

and I can seemingly grab any key and stuff it into a variable like this, right?:

_userId = ht["id"].ToString();

but when I request the scores of everyone playing my game:?

void onGetScore()

    {
        Facebook.instance.graphRequest( "AppID/scores", HTTPVerb.GET, ( error, obj ) =>
        {
            // if we have an error we dont proceed any further
            if( error != null )
                return;

            if( obj == null )
                return;
            // grab the userId and persist it for later use
            var ht = obj as Dictionary<string, object>;
            _score = ht["score"].ToString();
            Prime31.Utils.logObject( ht );
        } );
    }

It returns a nested dictionary/list like this:

 --------- IDictionary --------- 

 --------- IList --------- 
data: 
    --------- IDictionary ---------
    user:    --------- IDictionary ---------
        name:   Mike O'Connor
        id:     ##########
        score:  5677
        application:     --------- IDictionary ---------
            name:   ##########
            namespace:  ##########
            id:     ##########

now it's nested so I can't use this, right?

_score = ht["score"].ToString();

How do I get at the nested keys? Is it just a syntax problem or do I have to recast (or something else)?


Solution

  • So you want to access the value of a key-value pair inside a dictionary, inside a dictionary, inside a list, inside a dictionary?

    It sounds like you want this:

    _score = ht["data"][0]["score"].ToString();
    

    Note, the 0 here represents the first item in the ht["data"] list.

    Unfortunately it looks like your objects are probably weakly typed. In that case you'd have to do:

    _score = 
        ((IDictionary<string, object>)
            ((IList<object>)ht["data"])[0])["score"].ToString();
    

    Which looks terrible, but should work (assume the types returned are really what you describe).

    To get an set of user name / score pairs, you can use something like this Linq query:

    var scores = 
        from item in ((IList<object>)ht["data"]).Cast<IDictionary<string, object>>()
        let name = ((IDictionary<string, object>)item["user"])["name"].ToString()
        let score = item["score"].ToString()
        select new { username = name, score };