将2个列表与LINQ进行比较

时间:2013-03-04 20:11:41

标签: c# linq

我想从dateRange获取所有日期值,其中每个日期时间为DayOfWeek.Friday,... Monday,... Sunday

Intersect不起作用,因为我猜这两个列表不是真正的交叉点......而且它们有不同的类型:DateTime vs. Enum.DayOfWeek

这给了我所有星期五但我也想要星期一,星期日...而不使用OR运算符。

var dateRange = _dateService.GetDateRange(startDate, endDate).Where(d => visibleWeekDays.Any(v => d.DayOfWeek == v)).ToList();

这些都是我必须以某种方式比较的列表:

IEnumerable<DateTime> dateRange = _dateService.GetDateRange(startDate, endDate);
IEnumerable<DayOfWeek> visibleWeekDays = new List<DayOfWeek>
{
    DayOfWeek.Friday,
    DayOfWeek.Monday,
    DayOfWeek.Sunday,
};

请不要将完整的查询作为解决方案编写。 只需按随机顺序编写linq扩展方法我就要用来解决这个谜语。 只是为了乐趣和学习的缘故:)

更新

查看我的输入日期时间值和我想要的输出:

enter image description here

但请注意,visibleWeekDays列表不是静态的。此集合中可以包含动态数量的值。因此我可以而且不想使用&amp;&amp; amp;或||操作

4 个答案:

答案 0 :(得分:1)

如果您发现自己处于想要交叉点的位置,但两个集合的类型不同,通常意味着您需要Join。根据定义,交集是两个集合属于同一类型的连接,其中键选择器是“自身”,并且结果选择器只是随机选择其中一个项目(因为它们必须相等,交集的定义)。由于并非所有这些限制都适用于您所有您需要做的就是走出更为一般的Join

正如此演示一样,此处是Intersect仅使用Join的实现:

public static IEnumerable<T> Intersect<T>(this IEnumerable<T> first
    , IEnumerable<T> second, IEqualityComparer<T> comparer)
{
    return first.Join(second, x => x, x => x, (a, b) => a, comparer);
}

DayOfWeek只能将自己选为关键字,然后您只需要一种方法从密钥选择器的DayOfWeek中获取DateTime个对象。对于结果选择器,您只需要抓取DateTime对象;你不应该再需要DayOfWeek个对象了。

每当您发现自己在Where(x => collection.Any(...赔率范围内编写了ContainsWhere或其他搜索操作的LINQ解决方案时,您应该使用Join相反,如果适用(你至少应该问自己是否应该使用Join)。

由于你不想要一个完整的实现,我将它放在一个剧透标签中。如果你想自己编写代码,请不要看它:

  

public static IEnumerable FilterDaysOfWeek(IEnumerable dates
    , IEnumerable daysOfWeek)
{
     return dates.Join(daysOfWeek
         , date => date.DayOfWeek
         , day => day
         , (date, day) => date);
 }

答案 1 :(得分:0)

如果您将DayOfWeek转换为整数,则可以执行简单的&gt;和&lt;比较以获得有效值,所以只需要一个。查询应该是好的。

答案 2 :(得分:0)

如果您希望获得GetDateRangeDayOfWeekvisibleWeekdays中的 _dateService.GetDateRange(startDate, endDate) .Where(d=> visibleWeekdays.Contains(d.DayOfWeek)); 匹配的所有日期,您可以使用以下Linq语句:

class Test
    {
        static void Main(string[] args)
        {
            var weekdays = new[] { DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday };
            var result = GetDateRange(DateTime.Today, DateTime.Today.AddDays(14))
                .Where(d => weekdays.Contains(d.DayOfWeek));
        }

        public static IEnumerable<DateTime> GetDateRange(DateTime start, DateTime end)
        {
            DateTime date = start;

            do
            {
                yield return date;
                date = date.AddDays(1);
            }
            while (date < end);
        }
    }

以下是对此的全面测试:

{{1}}

答案 3 :(得分:0)

您可以在Contains条款的visibleWeekDays上使用Where