【问题标题】:Check and Update only time of DateTime Value in List<Dictionary<string, object>> using linq使用 linq 仅检查和更新 List<Dictionary<string, object>> 中 DateTime 值的时间
【发布时间】:2019-05-20 19:14:37
【问题描述】:

如何检查 DateTime 是否具有 0 小时 0 分钟和 0 秒,并仅更新 List&lt;Dictionary&lt;string, object&gt;&gt; 中特定键的时间值?

使用普通的 For 循环完成,但我如何使用 linq 来完成此操作

工作代码:

using System;
using System.Collections;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var data = new List<Dictionary<string, object>>();

        var d1 = new Dictionary<string, object>();
        d1.Add("START", new DateTime(2019, 05, 12));
        d1.Add("END", new DateTime(2019, 05, 14));
        d1.Add("Room1", "Room1");

        var d2 = new Dictionary<string, object>();
        d2.Add("START", new DateTime(2019, 05, 12));
        d2.Add("END", new DateTime(2019, 05, 14));
        d2.Add("Room2", "Room2");

        var d3 = new Dictionary<string, object>();
        d3.Add("START", new DateTime(2019, 05, 12));
        d3.Add("END", new DateTime(2019, 05, 14));
        d3.Add("Room3", "Room3");

        data.Add(d1);
        data.Add(d2);
        data.Add(d3);

        if (data != null)
        {
            for (int i = 0; i < data.Count; i++)
            {
                DateTime dt = (DateTime)data[i]["END"];
                Console.WriteLine("Before :" + data[i]["END"].ToString());
                if (dt.Hour == 0 && dt.Minute == 0 && dt.Second == 0)
                {
                    dt = dt.AddHours(23).AddMinutes(59).AddSeconds(59);
                    data[i]["END"] = dt;
                }
                Console.WriteLine("After :" + data[i]["END"].ToString());
            }
        }
    }
}

输出如下:

Before :5/14/2019 12:00:00 AM
After :5/14/2019 11:59:59 PM
Before :5/14/2019 12:00:00 AM
After :5/14/2019 11:59:59 PM
Before :5/14/2019 12:00:00 AM
After :5/14/2019 11:59:59 PM

【问题讨论】:

  • 出于好奇,为什么要改用 LINQ?
  • LINQ 是一个查询框架,你不要使用 LINQ 来更新东西
  • 最小化迭代,这里是 n 次迭代,但是通过在 linq 中应用 where 子句作为 key 和 datetime 将提高性能
  • 您在Dictionary&lt;string, object&gt; 中使用object 的事实表明这不适合您的数据。为什么不为预订创建一个类,包含开始、结束和房间号的属性。然后,您可以封装将结束日期设置为午夜前一分钟的行为。
  • @GaneshJangam 这是一个糟糕的建议。您必须围绕框架工作的事实应该告诉您您做错了。此外,List&lt;T&gt;.ForEach 不是 LINQ 方法,它是List&lt;T&gt; 类中的方法

标签: c# linq dictionary


【解决方案1】:

试试下面的代码。这只会从时间为00:00:00data 返回Dictionary&lt;string, object&gt;(就像您的示例代码一样)。它使用Where 子句提取日期,然后使用Select 创建新的数据列表,但更改了END 值。这将保留其他键的其他值。

var newData = (from dt in data
                where (((DateTime)dt["END"]).Hour == 0 && ((DateTime)dt["END"]).Minute == 0 && ((DateTime)dt["END"]).Second == 0)
                select new Dictionary<string, object>(dt.ToDictionary(kvp => kvp.Key, kvp => kvp.Key == "END" ? ((DateTime)kvp.Value).AddHours(23).AddMinutes(59).AddSeconds(59) : kvp.Value))
                ).ToList();

for (int i = 0; i < newData.Count; i++)
    Console.WriteLine(newData[i]["END"].ToString());

这里是一样的东西,只是写法不同。选择什么更具可读性。

var newData = data.Where(dt => ((DateTime)dt["END"]).Hour == 0 && ((DateTime)dt["END"]).Minute == 0 && ((DateTime)dt["END"]).Second == 0)
                    .Select(dt => new Dictionary<string, object>(dt.ToDictionary(kvp => kvp.Key, kvp => kvp.Key == "END" ? ((DateTime)kvp.Value).AddHours(23).AddMinutes(59).AddSeconds(59) : kvp.Value)))
                    .ToList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多