我不确定这是否可行。 我的班级我有一个这样的列表:
class Person
{
string Firstname
string Lastname
DateTime Timestamp
}
现在我想创建群组 名字和姓氏。
我还希望排序这些群组的时间戳,最后应该是第一个,而群组应保持显示在listView。
Markus Fert(群组标题)
11:23(内容元素)
John Deer
11:12
6:34
汤姆健
4:22
3:49
John Deer
3:12
汤姆健
1:22
希望任何Linq天才能帮我解决问题:) 谢谢!
非常感谢谢尔盖,工作就像一个魅力!
此外,我想为我的群组密钥创建自定义类,以在我的ListView标头中显示不同的其他内容。 (不仅是拼接在一起的字符串)
我想将我的查询分配给这样的IEnumerable:
IEnumerable<IGrouping<Header, Person>> PersonGroups
标题包含每个Person中包含的一些其他属性(例如,每个Person还有一个Country,Age,...)。也许你也可以帮助我吗?
再次感谢谢尔盖。通过实现实现ICompareable接口的Header类解决了我的问题。
IEnumerable<IGrouping<Header, Person>> PersonGroups
public class Header: IComparable<Header>
{
public Header(string firstname, string lastname)
{
Firstname= firstname;
Lastname = lastname;
}
public string Firstname{ get; set; }
public string Lastname{ get; set; }
public int CompareTo(Header that)
{
if (this.Firstname == that.Firstname&& this.Lastname == that.Lastname)
return 0;
else
return -1;
}
}
我的查询现在看起来像这样:
PersonGroups= persons.OrderByDescending(p => p.Timestamp)
.GroupConsecutive(p => new Header(p.Firstname, p.Lastname));
答案 0 :(得分:1)
实际上,您需要先按时间戳排序结果。然后才由连续的人对这个有序序列进行分组:
var query =
people.OrderByDescending(p => p.Timestamp.TimeOfDay)
.GroupConsecutive(p => String.Format("{0} {1}", p.Firstname, p.Lastname))
.Select(g => new {
Header = g.Key,
Content = String.Join("\n", g.Select(p => p.Timestamp.TimeOfDay))
});
您需要GroupConsecutive实现,它会根据提供的选择器的相同值(在您的情况下为全名)创建连续项目组。
对于您的样本输入结果是:
[
{
"Header": "Markus Fert",
"Content": "11:23:00"
},
{
"Header": "John Deer",
"Content": "11:12:00\n06:34:00"
},
{
"Header": "Tom Kin",
"Content": "04:22:00\n03:49:00"
},
{
"Header": "John Deer",
"Content": "03:12:00"
},
{
"Header": "Tom Kin",
"Content": "01:12:00"
}
]
答案 1 :(得分:0)
以下是使用内置链接运算符Aggregate
的方法。
首先,我需要通过降序时间戳来对列表进行排序,然后创建一个名称格式化函数。
var op = people
.OrderByDescending(p => p.Timestamp)
.ToArray();
Func<Person, string> toName = p =>
String.Format("{0} {1}", p.Firstname, p.Lastname);
现在我可以构建查询:
var query =
op
.Skip(1)
.Aggregate(new []
{
new
{
Name = toName(op.First()),
Timestamps = new List<string>()
{
op.First().Timestamp.ToShortTimeString(),
},
},
}.ToList(), (a, p) =>
{
var name = toName(p);
if (name == a.Last().Name)
{
a.Last().Timestamps.Add(p.Timestamp.ToShortTimeString());
}
else
{
a.Add(new
{
Name = name,
Timestamps = new List<string>()
{
p.Timestamp.ToShortTimeString(),
},
});
}
return a;
});
我得到了这个结果: