0

How can i check if DateTime having 0 hours 0 minutes and 0 second and update only time value in List<Dictionary<string, object>> for specific key?

Done with normal For loop, but how can i do this with linq

Working code:

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());
            }
        }
    }
}

OutPut as Below:

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
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Ganesh Jangam
  • 97
  • 1
  • 4
  • 15
  • 1
    Out of curiosity, why the desire to change to LINQ? – Broots Waymb May 20 '19 at 19:19
  • 2
    LINQ is a query framework, you don't use LINQ to update stuff – Camilo Terevinto May 20 '19 at 19:23
  • minimizing iterations, here is n no of iterations but by applying where clause for key and datetime in linq will improve performance – Ganesh Jangam May 20 '19 at 19:25
  • 5
    The fact that you're using `object` in `Dictionary` suggests that this is not a good "fit" for your data. Why not create a class for the bookings, containing properties for the start, end and room number. You can then encapsulate the behaviour of setting the end date to a minute before midnight. – iakobski May 20 '19 at 19:29
  • @CamiloTerevinto we can update using ForEach like https://stackoverflow.com/questions/398871/update-all-objects-in-a-collection-using-linq – Ganesh Jangam May 20 '19 at 19:33
  • 2
    @GaneshJangam That's a *terrible* suggestion. The fact that you have to work around the framework should tell you you are doing it wrong. Also, `List.ForEach` is **not** a LINQ method, it's a method in the `List` class – Camilo Terevinto May 20 '19 at 19:37
  • Yep. AFAIK `List.ForEach` is part of the TPL - Task Parallel Library and has a whole other use. – LuckyLikey May 20 '19 at 20:32

1 Answers1

1

Try the code below. This will only return the Dictionary<string, object> from data where the time was 00:00:00 (just like your sample code). It uses a Where clause to pull the dates and then uses Select to create a new list of the data, but changes the END value. This will keep the other values for the other keys.

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());

Here is the same thing, just written a different way. Take your pick as to what is more readable.

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();
dvo
  • 2,113
  • 1
  • 8
  • 19