我有一个简单的课:
class SimpleDevice
{
public string IMEI {get;set;}
public long Timestamp {get;set;}
}
以及一种用于测试目的生成列表的方法:
private static List<SimpleDevice> GenerateListOfDevices()
{
return new List<SimpleDevice>()
{
new SimpleDevice { IMEI = "bbbbb", Timestamp = 33 },
new SimpleDevice { IMEI = "bbbbb", Timestamp = 45 },
new SimpleDevice { IMEI = "aaaaa", Timestamp = 36 },
new SimpleDevice { IMEI = "aaaaa", Timestamp = 37 },
new SimpleDevice { IMEI = "aaaaa", Timestamp = 35 },
new SimpleDevice { IMEI = "bbbbb", Timestamp = 34 },
new SimpleDevice { IMEI = "aaaaa", Timestamp = 39 },
new SimpleDevice { IMEI = "aaaaa", Timestamp = 38 },
new SimpleDevice { IMEI = "bbbbb", Timestamp = 35 }
};
}
我想将List<SimpleDevice>
分成List<List<SimpleDevice>>
,其中嵌套列表按IMEI
分组。
然后,我想按内部列表的Timestamp
对其进行排序,因此我对每个列表都有一个顺序输出。
这是我的LINQ
声明:
private static List<List<SimpleDevice>> SplitAndSort (List<SimpleDevice> devices)
{
return devices
.Select(x => x)
.GroupBy(x => x.IMEI)
.Select(x => x.Select(y => y).ToList())
.OrderBy(x => x.Select(y => y.Timestamp))
.ToList();
}
哪个抛出以下异常:
内部异常System.ArgumentException:至少一个对象必须实现IComparable
OrderBy(x => x.Select(y => y.Timestamp))
中发生了什么。
我有一个Google,发现OrderedBy
所在的类型必须实现IComparable
,而long
类型可以做到:
public struct Int64 : IComparable, IComparable<Int64>, ...
将内部x => x.Select(...
内的OrderBy
更改为x => x.Min(...
可以编译和运行我的代码,但是内部列表并未按其Timestamp
进行排序拆分工作:
IMEI: bbbbb, Timestamp: 33
IMEI: bbbbb, Timestamp: 45
IMEI: bbbbb, Timestamp: 34
IMEI: bbbbb, Timestamp: 35
IMEI: aaaaa, Timestamp: 36
IMEI: aaaaa, Timestamp: 37
IMEI: aaaaa, Timestamp: 35
IMEI: aaaaa, Timestamp: 39
IMEI: aaaaa, Timestamp: 38
尝试按升序排列内部列表时,我是否缺少明显的东西?
答案 0 :(得分:3)
您的查询有点混乱。
您将OrderBy
放在错误的位置-它在外部列表而不是内部列表上起作用。因此,例外。
在选择(生成)嵌套列表时进行排序:
private static List<List<SimpleDevice>> SplitAndSort(List<SimpleDevice> devices)
{
return devices
.GroupBy(x => x.IMEI)
.Select(g => g.Select(y => y).OrderBy(x => x.Timestamp).ToList())
.ToList();
}
请注意,取出.Select(y=>y)
,OrderBy
就足够了。 (我没有在上面删除)
答案 1 :(得分:2)
以下应做您想做的事:
private static List<List<SimpleDevice>> SplitAndSort (List<SimpleDevice> devices)
{
return devices
.GroupBy(x => x.IMEI)
.Select(x => x.OrderBy(y=> y.TimeStamp).ToList())
.ToList();
}
让我引导您完成它:
.GroupBy(x => x.IMEI)
1。通过IMEI对列表进行分组。您现在有了一个类型为IEnumerable
.Select(x => x.OrderBy(y=> y.TimeStamp).ToList())
在每个组中,按时间戳顺序排序,然后调用ToList()来给您内部列表。此时,您具有IEnumerable >
.ToList();
最后一个ToList将为您提供List >
答案 2 :(得分:2)
好吧,让我试着向你扔这个。
首先,您要确保列表为ordered by
Timestamp
,因此现在您知道列表顺序是正确的,然后执行GroupBy
和。Select(x => x.Select(y => y).ToList())
,这将给出您List<List<SimpleDevice>>
List<List<SimpleDevice>> test = devices
.OrderBy(x=> x.Timestamp)
.GroupBy(x => x.IMEI)
.Select(x => x.Select(y => y).ToList())
.ToList();
这是结果
bbbbb 33
bbbbb 34
bbbbb 35
bbbbb 45
aaaaa 35
aaaaa 36
aaaaa 37
aaaaa 38
aaaaa 39
答案 3 :(得分:0)
第二个选择将生成列表列表。 Order by还选择一个列表作为比较值,该列表未实现IComparable
。如果您添加.FirstOrDefault ()
或类似名称,则可以使用。
devices
.GroupBy(x => x.IMEI)
.Select(x => x.OrderBy(y => y.Timestamp).ToList()) // <- order inner list here
//.OrderBy(x => x.Select(y => y.Timestamp)) // you don't need this line then
.ToList();