I have a List(Of DateTime) items. How can I check if all the items are the same with a LINQ query? At any given time there could be 1, 2, 20, 50 or 100 items in the list.
            Asked
            
        
        
            Active
            
        
            Viewed 9.3k times
        
    5 Answers
151
            Like this:
if (list.Distinct().Skip(1).Any())
Or
if (list.Any(o => o != list[0]))
(which is probably faster)
 
    
    
        SLaks
        
- 868,454
- 176
- 1,908
- 1,964
- 
                    28Potentially easier to read with "All" instead of "Any". You may also want to use First() instead of [0] in case list access cannot be performed (IEnumerable). if (list.All(o => o == list.First())) { ... } – Graeme Wicksted Sep 08 '14 at 21:00
- 
                    4`list.Distinct().Skip(1).Any()` is no different than `list.Distinct().Count != 1` right? – Simon_Weaver Sep 17 '16 at 19:15
- 
                    1@GraemeWicksted the whole point of Any() is to be faster if one item is found that DOESN'T match. Then you stop evaluating the list. What IS slightly clearer though is `!(list.Any(o => o != list[0]))` which is true if there are no items that are different from the first one - i.e. if they're all the same – Simon_Weaver Sep 17 '16 at 19:21
- 
                    10@Simon_Weaver `Any()` is used to find at least 1 match while `All()` is used to ensure all items match. In either case, if a non-match is encountered in All or a match is found in Any, they will halt iteration. So `!(list.Any(o => o != list[0]));` and `list.All(o => o == list[0]);` will always have the same iteration count. Thus both will have about the same execution time. P.S. You are correct, in that `list.Distinct().Skip(1).Any()` is analogous to `list.Distinct().Count != 1` just be aware Count can be slower than Any (possibly even in this case) with > 1 element. – Graeme Wicksted Sep 19 '16 at 00:57
- 
                    But count has to iterate over the entire distinct list. If you have more than 2 sets, it's slower. – Lee Louviere Sep 16 '19 at 15:53
17
            
            
        I created simple extension method mainly for readability that works on any IEnumerable.
if (items.AreAllSame()) ...
And the method implementation:
    /// <summary>
    ///   Checks whether all items in the enumerable are same (Uses <see cref="object.Equals(object)" /> to check for equality)
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="enumerable">The enumerable.</param>
    /// <returns>
    ///   Returns true if there is 0 or 1 item in the enumerable or if all items in the enumerable are same (equal to
    ///   each other) otherwise false.
    /// </returns>
    public static bool AreAllSame<T>(this IEnumerable<T> enumerable)
    {
        if (enumerable == null) throw new ArgumentNullException(nameof(enumerable));
        using (var enumerator = enumerable.GetEnumerator())
        {
            var toCompare = default(T);
            if (enumerator.MoveNext())
            {
                toCompare = enumerator.Current;
            }
            while (enumerator.MoveNext())
            {
                if (toCompare != null && !toCompare.Equals(enumerator.Current))
                {
                    return false;
                }
            }
        }
        return true;
    }
 
    
    
        MSkuta
        
- 1,630
- 13
- 19
- 
                    1Nice! Just wondering about the empty list implementation. I'm not sure if I would assume that an empty list means "all are the same" - feels like a case for the consumer to handle, so I think I'm going to throw if the list empty. "Are the apples the same? No clue, because there are no apples in the basket" – Dirk Boer Oct 18 '19 at 07:54
- 
                    This extension does not work in cases where the IEnumerable contains null values. For this case I added `if (toCompare == null && enumerator.Current != null) { return false; }` – MatterOfFact Mar 12 '23 at 08:29
14
            
            
        My variant:
var numUniques = 1;
var result = list.Distinct().Count() == numUniques;
 
    
    
        Seva
        
- 1,631
- 2
- 18
- 23
- 
                    2I like this, it's very readable and shows intent compared to the skip1/any solution. – tkit Nov 29 '19 at 11:51
9
            
            
        This is an option, too:
 if (list.TrueForAll(i => i.Equals(list.FirstOrDefault())))
It is faster than if (list.Distinct().Skip(1).Any()) , and performs similarly as 
  if (list.Any(o => o != list[0])), however, the difference is not significant, so I suggest using the more readable one.
 
    
    
        KungFury
        
- 91
- 1
- 3
4
            
            
        VB.NET version:
If list.Distinct().Skip(1).Any() Then
Or
If list.Any(Function(d) d <> list(0)) Then
 
    
    
        jor
        
- 2,058
- 2
- 26
- 46
 
    