4

在我的 c# MVC4 应用程序中,我有一个字符串列表。列表中的每个奇数元素都是一个日期时间。它们每个之前的偶数元素是唯一标识符。

例如:[0] 是 A7M0066 [1] 是 2007-01-06 06:24:00.000

我想处理列表并将奇数元素中基于日期时间的前 5 个最近对添加到另一个字符串列表中。我不确定从哪里开始,但我假设它需要 LINQ。

使用下面基思的回答和测试,我意识到我真正需要的已经改变了。使用他的方法,我得到 5 个最近的结果,但其中 3 个具有相同的 id。我需要最终结果所有人都有一个唯一的 ID。基本上我需要保留 3 个条目中的 1 个相同并继续处理,直到所有 5 个条目都是唯一的。

4

5 回答 5

8

我认为你对这一切都是错误的。由于这些“对”是相关的,让我们为它们创建一个类。

public class DateTimePairs(){ 

   public string Id {get;set;}

   public DateTime Date {get;set;}
}

现在,让我们列出这些:

var MyList = new List<DateTimePairs>();
MyList = 'Get your values for the list

最后,返回你想要的东西真的很简单

return MyList.OrderByDescending(x=>x.Date).Take(5);
于 2013-04-25T21:00:03.713 回答
8
var items =
    list.Where((x, i) => i%2 == 0)
        .Zip(list.Where((x, i) => i%2 == 1), (f, s) => new {Id = f, Date = s})
        .OrderByDescending(x => x.Date)
        .DistinctBy(x => x.Id, null)   // see note later in this answer....
        .Take(5)
        .ToList();

这将使用奇数元素压缩偶数元素,并将它们转换为具有 Id 和 Date 作为字段的对象。然后按日期排序,取最近的 5 个

这样您就可以遍历每个对象并按照您的意愿进行操作。

即,用于将 5 打印到控制台的示例...

items.ForEach(x => Console.WriteLine("{0} {1}", x.Id, x.Date));

用最大的日期做唯一的 ID .....参考LINQ: Distinct values

并使用 Skeet 先生展示的扩展方法......除了我已经改进了一点,我的版本是:-

public static class DistinctLinq
    {
        public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
            this IEnumerable<TSource> source,
            Func<TSource, TKey> keySelector,
            IEqualityComparer<TKey> comparer)
        {
            var knownKeys = new HashSet<TKey>(comparer);
            return source.Where(element => knownKeys.Add(keySelector(element)));
        }
    }
于 2013-04-25T21:08:03.703 回答
4

你可以这样做:

var results =
    (from i in Enumerable.Range(0, myList.Length / 2)
     let Guid = Guid.Parse(myList[i * 2])
     let Date = DateTime.Parse(myList[i * 2 + 1])
     orderby Date descending
     return new { Guid, Date })
    .Take(5);
于 2013-04-25T21:00:11.763 回答
1

扩展基思的回答,考虑以下方法,它解析日期本身。我添加它不是因为您需要它来进行简单的排序(您的日期格式将允许这样做) - 而是因为如果您开始基于 Dates 进行其他类型的比较,您可能需要它。

var dt = DateTime.MinValue;
var items = list.Where((x, i) => i % 2 == 0)
.Zip(list.Where((x, i) => i % 2 == 1), (f, s) => new { 
    Id = f, 
    Date = DateTime.TryParse(s, out dt) ? (DateTime?)dt : null
})
.OrderByDescending(x => x.Date);

由于.TryParse()三元组,如果预期的奇数元素没有解析为有效DateTime对象,则返回null. 如果是这样,您将返回已解析的DateTime. 结果列表现在可以用于类型安全地比较坏数据(查找空值)或进行其他类型的DateTime比较/排序。

于 2013-04-25T21:37:18.077 回答
0

与 Zip 解决方案类似,我建议创建和使用更普遍有用的“分区”扩展方法(请参阅使用 LINQ 将列表拆分为子列表)。例如,使用返回 IEnumerable<List<T>> 的“Partition”扩展方法,实现是非常自我记录的:

var items = list.Partition(2).Take(5).ToList();

显然,最好将其转换为更强大的类型,但即使如此,您也可以使用以下方法提取值(假设 0 <= n <= items.Count):

 var id = items[n].FirstOrDefault();
 var date = items[n].ElementAtOrDefault(1);
于 2013-04-25T21:36:29.730 回答