C#/ Linq - 排序IDictionary

时间:2016-02-18 10:32:51

标签: c# linq unity3d firebase

我正在使用Firebase for Unity来存储一些得分的用户。 Firebase会将我的用户列表作为IDictionary<string, object>返回,其中Key是Firebase生成的ID,而Value是代表用户的另一个IDictionary<string, object>

用户有Key名为&#34;得分&#34;我想按排行榜得分的Value对所有用户进行排序。

这或多或少的数据看起来像JSON:

"users": {
  "<userid>" : {
    "name" : "John",
    "score": 5
    ...  
  },
  "<userid>" : {
    "name" : "Pete",
    "score" : 10
  }
  ... 
}

我如何排序用户列表?我假设我需要以某种方式使用Linq,但我仍然在努力掌握它是如何工作的。

真的很感激一些帮助。 谢谢!

4 个答案:

答案 0 :(得分:1)

假设:

IDictionary<string, object> dict = new Dictionary<string, object>() {
    { "1", new Dictionary<string, object>() 
        {
            { "name", "John" },
            { "score", 5 }
        }
    },
    { "2", new Dictionary<string, object>() 
        {
            { "name", "Pete" },
            { "score", 4 }
        }
    },
};

你可以:

var ordered = dict.OrderBy(x => (int)((IDictionary<string, object>)x.Value)["score"]).ToArray();

这很难看,如果score丢失,那么你会得到一个例外。

如果score可能丢失:

public static TValue GetValueOrDefault<TKey, TValue>(IDictionary<TKey, TValue> dict, TKey key)
{
    TValue value;
    dict.TryGetValue(key, out value);
    return value;
}

然后

var ordered = dict.OrderBy(x => (int?)GetValueOrDefault((IDictionary<string, object>)x.Value, "score")).ToArray();

答案 1 :(得分:0)

IEnumerable<User> OrderByScore(IDictionary<string,object> firebaseList)
{
    return from user in firebaseList.Values.Cast<IDictionary<string,object>>()
        let name  = (string) user["name"]
        let score = int.Parse(user["score"].ToString())
        orderby score descending
        select new User { Name = name, Score = score};
}

class User
{
    public string Name  {get;set;}
    public int    Score {get;set;}
}

答案 2 :(得分:0)

其他评论和答案侧重于过滤用户端的用户。这个答案是关于使用Firebase的内置查询功能来过滤服务器上的数据,遗憾的是,这些数据尚未在Unity库中提供。

从此post on the firebase-talk Google Group

  

目前,[Firebase库]仅支持您在完整平台上找到的功能的子集。   统一sdk的工作方式是它使用互操作来对抗完整的sdk。那些方法就在那里,它们只是没有曝光。

     

我们接受拉取请求。 [如果您对贡献感兴趣],请查看:

  

它可能会给你足够的想法来添加额外的方法。

     

支持桌面播放器(能够播放)有点复杂,但启用iOS和Android查询应该不会非常复杂。

这个主题还很新鲜,所以如果你有其他问题我建议你把它们发布在那里。

答案 3 :(得分:0)

const string scoreKey = "score";
const string nameKey = "name";
var highscores = userDict
                .OrderByDescending(u => ((IDictionary<string, object>)u.Value)[scoreKey])
                .Select(u => new {
                        Name = ((IDictionary<string, object>)u.Value)[nameKey], 
                        Score = ((IDictionary<string, object>)u.Value)[scoreKey]
                    }
                 );

Fiddle