我有一个这样的对象列表:
public class ExceptionFolderEntries
{
public int Id { get; set; }
public string Data { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
}
无论是否为结束时间的开始时间,我都在尝试获取下一个“时间”,以便我可以采取措施。 我知道如何使用基于StartTime或EndTime的LINQ来排序列表,但是不知道如何合并数据,然后对新合并的列表进行排序。
示例: 带有数据:
“ ABC”,“ 1/1/2018 01:00”,“ 1/2/2018 13:00”
“ MNO”,“ 1/1/2018 01:30”,“ 1/1/2018 08:00”
“ XYZ”,“ 1/1/2018 09:00”,“ 1/2/2018 13:00”
会导致
ABC 1/1 01:00
MNO 1/1 01:30
MNO 1/1 08:00
XYZ 1/1 09:00
ABC 1/2 13:00
XYZ 1/2 13:00
有什么建议吗?
答案 0 :(得分:1)
您可以尝试创建两个FolderEntries
新创建集合,一个用于StartTime
,另一个用于EndTime
,然后使用linq Concat
组合两个集合。然后做order by
public class FolderEntries {
public string Data { get; set; }
public DateTime? FolderDateTime { get; set; }
}
var result =
(from s1 in list select new FolderEntries(){
Data = s1.Data,
FolderDateTime = s1.StartTime
}).Concat
(from s2 in list select new FolderEntries {
Data = s2.Data,
FolderDateTime = s2.EndTime
}).OrderBy(x=>x.FolderDateTime);
结果
ABC 1/1/2018 1:00:00 AM
MNO 1/1/2018 1:30:00 AM
XYZ 1/1/2018 9:00:00 AM
MNO 1/1/2018 1:08:00 PM
ABC 1/2/2018 1:00:00 PM
XYZ 1/2/2018 1:00:00 PM
答案 1 :(得分:1)
我的答案也许与Eriks答案太相似,但是一种解决方法是选择一个新的ExceptionFolderEntries
(由于它只代表一个项目,因此应真正重命名为ExceptionFolderEntry
)。每个非空的StartTime
和EndTime
,保留我们正在读取的那个(开始或结束),并保留另一个字段null
。
然后,您可以按非空值StartTime ?? EndTime
来订购新的(可调整的)列表。
例如:
var sortedItems =
// First select a new item for all non-null StartTimes
items.Where(i => i.StartTime.HasValue)
.Select(i => new ExceptionFolderEntries {Data = i.Data, StartTime = i.StartTime})
// Then concat with a new item for all non-null EndTimes
.Concat(items
.Where(i => i.EndTime.HasValue)
.Select(i => new ExceptionFolderEntries {Data = i.Data, EndTime = i.EndTime}))
// And finally, order by the non-null field
.OrderBy(i => i.StartTime ?? i.EndTime)
.ToList();
// Now we can write out the data and the non-null field for each item
sortedItems.ForEach(i => Console.WriteLine($"{i.Data} {i.StartTime ?? i.EndTime}"));
输出
在上面的示例中,items
初始化为:
var items = new List<ExceptionFolderEntries>
{
new ExceptionFolderEntries
{
Data = "ABC",
StartTime = DateTime.Parse("1/1/2018 01:00"),
EndTime = DateTime.Parse("1/2/2018 13:00")
},
new ExceptionFolderEntries
{
Data = "MNO",
StartTime = DateTime.Parse("1/1/2018 01:30"),
EndTime = DateTime.Parse("1/1/2018 08:00")
},
new ExceptionFolderEntries
{
Data = "XYZ",
StartTime = DateTime.Parse("1/1/2018 09:00"),
EndTime = DateTime.Parse("1/2/2018 13:00")
},
};
答案 2 :(得分:0)
ExceptionFolderEntries[] entries = [];
entries.Select(e => new DateTime?[] {e.StartTime, e.EndTime).SelectMany(dt => dt).OrderBy(//ordery by logic)
首先将日期时间选择到一个数组中(创建一个数组数组),然后使用select many将其展平。
编辑:也可以缩短
ExceptionFolderEntries[] entries = [];
entries.SelectMany(e => new DateTime?[] {e.StartTime, e.EndTime).OrderBy(//ordery by logic)
答案 3 :(得分:0)
首先,您的课程可能不应以(s)
结尾,因为它不是集合,因此在示例中将使用ExceptionFolderEntry
。
我可能会做类似的事情:
class ExceptionFolderEntryMeta
{
public ExceptionFolderEntry ExceptionFolderEntry { get; set; }
public DateTime SortBy { get; set; }
public bool IsStartTime { get; set; }
}
var exceptionFolderEntries = new List<ExceptionFolderEntry>();
var mergeList = exceptionFolderEntries
.Where(efe => efe.StartTime.HasValue)
.Select(efe => new ExceptionFolderEntryMeta
{
ExceptionFolderEntry = efe,
SortBy = efe.StartTime,
IsStartTime = true,
})
.Concat(exceptionFolderEntries
.Where(efe => efe.EndTime.HasValue)
.Select(efe => new ExceptionFolderEntryMeta
{
ExceptionFolderEntry = efe,
SortBy = efe.EndTime,
IsStartTime = false,
}))
.OrderBy(efem => efem.SortBy)
.ToList())
我创建了新类,以便进行正确的排序并指示它是开始时间还是结束时间(因为您可能需要在某个时候知道这一点)。我还考虑到您已将这些属性创建为可为空,因此,如果一个属性为null,则它仅出现一次,如果两个属性都为null,则永远不会出现。