C#/Linq - 对字典进行排序
Posted
技术标签:
【中文标题】C#/Linq - 对字典进行排序【英文标题】:C#/Linq - Sort IDictionary 【发布时间】:2016-05-30 11:18:14 【问题描述】:我正在使用 Firebase for Unity 来存储一些带有分数的用户。 Firebase 将我的用户列表返回为 IDictionary<string, object>
,其中 Key
是 Firebase 生成的某个 id,Value
是另一个代表用户的 IDictionary<string, object>
。
用户有一个名为“分数”的Key
,我想按照排行榜分数的Value
对所有用户进行排序。
这或多或少的数据看起来像 JSON:
"users":
"<userid>" :
"name" : "John",
"score": 5
...
,
"<userid>" :
"name" : "Pete",
"score" : 10
...
我将如何对用户列表进行排序?我认为我需要以某种方式使用 Linq,但我仍在努力掌握它的工作原理。
我们将不胜感激。 谢谢!
【问题讨论】:
您无法对IDictionary<K, V>
进行排序。它们没有定义的排序顺序。这就是SortedDictionary
存在的原因。除非你很高兴拥有IEnumerable<KeyValuePair<string, object>>
,否则你无法得到你想要的。
Dictionary
无法排序,请改用List
。
看this
您是在寻找真正对字典进行排序还是仅按特定顺序显示它们?
【参考方案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();
【讨论】:
【参考方案2】: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
【讨论】:
【参考方案3】: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;
【讨论】:
【参考方案4】:其他 cmets 和答案侧重于过滤用户客户端。这个答案是关于使用 Firebase 的内置查询功能来过滤服务器上的数据,遗憾的是 Unity 库中尚不提供该功能。
来自post on the firebase-talk Google Group:
目前,[Firebase for Unity 库] 仅支持您在完整平台上可以找到的部分功能。 unity sdk 的工作方式是它对完整的 sdk 使用互操作。所以这些方法是存在的,只是没有暴露出来。
我们接受拉取请求。 [如果您有兴趣贡献],请查看:
https://github.com/firebase/Firebase-Unity/blob/master/empty-project/Assets/Plugins/android/QueryAndroidImpl.cs
https://github.com/firebase/Firebase-Unity/blob/master/empty-project/Assets/Plugins/ios/QueryiOSImpl.cs
https://github.com/firebase/Firebase-Unity/blob/master/empty-project/Assets/Plugins/iOS/Firebase.mm
它可能会给你足够的想法来添加额外的方法。
支持桌面播放器(能够点击播放)有点复杂,但启用 iOS 和 Android 查询应该不会太复杂。
这个话题还是很新鲜的,所以如果您还有其他问题,我建议您在那里发布。
【讨论】:
以上是关于C#/Linq - 对字典进行排序的主要内容,如果未能解决你的问题,请参考以下文章