Click here to Skip to main content
15,888,113 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
C#
// create lists of potential start and end times in 15 min intervals from 8am-6pm (this results in two lists of datetimes). 
var initialTimes = InitialTimeList(15); 

// create lists of booked times (this results in two lists of datetimes) in 15 min intervals
var bookedTimes = BookedTimeList(bookedtimes, 15);

// remove duplicates from the initial time list
var availableTimes = initialTimes.Except(bookedTimes);



The problem is that it returns a compared lists but hasnt remove the duplicates... I'm not sure if it is possible for linq to compare a list array? Any suggestions would be greatly appreciated. Thanks in advance!!!

What I have tried:

I have tried using the except method with a single list and it works just fine. It returns the initial time list minus the booked times. Its only in the array that it just returns the initial list without excluding the booked times.
Posted
Updated 9-Aug-16 7:11am
v2
Comments
David_Wimbley 8-Aug-16 21:51pm    
Are you saying you just want a list of items that are not present, by date time, in another list?

Ex: List 1 -> 1,2,3,4
List 2 -> 2,4,5,6

Your result set when comparing List 2 to List one would be 5,6. Is that correct?
nebiam 8-Aug-16 23:08pm    
Yes. It sounds simple, but this is what is happening. For example..
List 1 -> 1234567
List 2 -> 123

Result should be 4567, but instead it shows the full results of list 1.

Remembering its in an array though.. so I have two lists, both with a start and end time..
Maciej Los 9-Aug-16 2:08am    
Could you be so kind and provide more details about your lists? Sample data may help us to suggest you a solution.

David's solution has a fundamental inefficiency. It iterates through the newbooks collection for each member of oldbooks. This makes it O(n*m) where n is the count of newbooks and m is the count of oldbooks.

Your initial attempt with .Except() was almost right!

Using David's Books class as the example:
You needed either to override the Equals() method of Books:
C#
public class Books
{
  public string Name { get; set; }
  public DateTime PublishDate { get; set; }

  public override bool Equals(object obj)
  {
    Books other = obj as Books;
    return other != null && this.PublishDate == other.PublishDate;
  }

  public override int GetHashCode()
  {
    return PublishDate.GetHashCode();
  }
}

// Then get the difference with:
var diff = oldbooks.Except(newbooks);

(If you override Equals it is very important to also override GetHashCode.)
This means that all comparisons of Books objects would consider only the PublishDate, and you couldn't do this for a different comparison later.

A more flexible way would be to implement a comparer class:
C#
public class Books
{
  public string Name { get; set; }
  public DateTime PublishDate { get; set; }
}

public class BooksDateComparer : IEqualityComparer<Books>
{
  public bool Equals(Books x, Books y)
  {
    //Check whether the compared objects reference the same data.
    if (Object.ReferenceEquals(x, y))
      return true;

    //Check whether any of the compared objects is null.
    if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
      return false;
    // compare the dates
    return x.PublishDate == y.PublishDate;
  }

  public int GetHashCode(Books obj)
  {
    //Check whether the object is null
    if (Object.ReferenceEquals(obj, null))
      return 0;
    return obj.PublishDate.GetHashCode();
  }
}

// This way get the difference with:
var diff = oldbooks.Except(newbooks, new BooksDateComparer());

Also, just for clarification: Linq works exactly the same on arrays as it does on List<T>. It only needs the collection to implement IEnumerable<T>.
 
Share this answer
 
Comments
David_Wimbley 9-Aug-16 13:38pm    
Nice, thanks for exanding upon this one. +5
Maciej Los 9-Aug-16 13:56pm    
5ed!
That's what i was talking about!
So since i don't know your data type, i created a class called Books to demonstrate a complex data type for this comparison.

C#
public class Books
{
    public string Name { get; set; }
    public DateTime PublishDate { get; set; }
}


Then the usage

C#
var newbooks = new List<Books>();
            var oldbooks = new List<books>();

            newbooks.Add(new Books { Name = "", PublishDate = new DateTime(2016, 1, 1) });
            newbooks.Add(new Books { Name = "", PublishDate = new DateTime(2016, 2, 1) });
            newbooks.Add(new Books { Name = "", PublishDate = new DateTime(2016, 3, 1) });

            oldbooks.Add(new Books { Name = "", PublishDate = new DateTime(2016, 1, 1) });
            oldbooks.Add(new Books { Name = "", PublishDate = new DateTime(2016, 2, 1) });
            oldbooks.Add(new Books { Name = "", PublishDate = new DateTime(2016, 3, 1) });
            oldbooks.Add(new Books { Name = "", PublishDate = new DateTime(2016, 4, 1) });

            var diff = oldbooks.Where(m=> !newbooks.Select(x=>x.PublishDate).Contains(m.PublishDate));

            foreach (var item in diff)
            {
                Console.WriteLine("Book name {0} - Publish Date {1}", item.Name, item.PublishDate);
            }


The output

C#
Book name  - Publish Date 4/1/2016 12:00:00 AM


So to get the items not in both lists you would use !.Contains for the comparison.
 
Share this answer
 
v2
Comments
nebiam 8-Aug-16 23:28pm    
The datatype is List<datetime>[] timeList = new List<datetime>[2];
David_Wimbley 8-Aug-16 23:36pm    
Your data type doesn't make sense. Thats not the syntax for declaring a list.

Eitherway, if you were using an array, you can convert your array to a list via .ToList() and use the same method provided in my answer to compare and get the difference.
Maciej Los 9-Aug-16 2:05am    
It's partially true for basic solution. For more advanced solutions, OP have to implement Equals method.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900