11using System ;
22using System . Collections ;
33using System . Collections . Generic ;
4+ using System . Diagnostics ;
45using System . Linq ;
5- using Utils ;
6+ using Extensions . Types ;
67
78namespace Extensions
89{
910 public static class IEnumerableExtensions
1011 {
11- public static void Each < T > ( this IEnumerable < T > source , Action < T > action ) => For . Each ( source , action ) ;
12+ // public static void Each<T>(this IEnumerable<T> source, Action<T> action) => For.Each(source, action);
1213
13- public static void Each < T > ( this IEnumerable source , Action < T > action ) => For . Each ( source , action ) ;
14+ // public static void Each<T>(this IEnumerable source, Action<T> action) => For.Each(source, action);
1415
1516 public static IEnumerable < T > Except < T > ( this IEnumerable < T > list , IEnumerable < T > except , Func < T , T , bool > comparer ) =>
1617 list . Except ( except , new KeyEqualityComparer < T > ( comparer ) ) ;
@@ -31,5 +32,81 @@ public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> enumerable, bool con
3132 public static IEnumerable < T > WhereIfElse < T > ( this IEnumerable < T > enumerable , bool condition , Func < T , bool > @if , Func < T , bool > @else ) =>
3233 condition ? enumerable . Where ( @if ) : enumerable . Where ( @else ) ;
3334
35+ /// <summary>
36+ /// Distinct by specific property.
37+ /// </summary>
38+ /// <param name="keySelector">Function to pass object for distinct to work.</param>
39+ public static IEnumerable < TSource > DistinctBy < TSource , TKey > ( this IEnumerable < TSource > source , Func < TSource , TKey > keySelector )
40+ {
41+ var seenKeys = new HashSet < TKey > ( ) ;
42+ foreach ( var element in source )
43+ {
44+ if ( seenKeys . Add ( keySelector ( element ) ) )
45+ {
46+ yield return element ;
47+ }
48+ }
49+ }
50+
51+ /// <summary>
52+ /// Checks whether all items in the enumerable are same (Uses <see cref="object.Equals(object)" /> to check for equality)
53+ /// </summary>
54+ /// <typeparam name="T"></typeparam>
55+ /// <param name="enumerable">The enumerable.</param>
56+ /// <returns>
57+ /// Returns true if there is 0 or 1 item in the enumerable or if all items in the enumerable are same (equal to
58+ /// each other) otherwise false.
59+ /// </returns>
60+ public static bool AreAllSame < T > ( this IEnumerable < T > enumerable )
61+ {
62+ if ( enumerable == null )
63+ throw new ArgumentNullException ( nameof ( enumerable ) ) ;
64+
65+ using ( var enumerator = enumerable . GetEnumerator ( ) )
66+ {
67+ var toCompare = default ( T ) ;
68+ if ( enumerator . MoveNext ( ) )
69+ {
70+ toCompare = enumerator . Current ;
71+ }
72+
73+ while ( enumerator . MoveNext ( ) )
74+ {
75+ if ( toCompare != null && ! toCompare . Equals ( enumerator . Current ) )
76+ {
77+ return false ;
78+ }
79+ }
80+ }
81+
82+ return true ;
83+ }
84+
85+ [ DebuggerStepThrough ]
86+ public static void Each < T > ( this IEnumerable < T > source , Action < T > action )
87+ {
88+ foreach ( var item in source )
89+ action ( item ) ;
90+ }
91+
92+ /// <summary>
93+ /// For shortcut, no side effects
94+ /// </summary>
95+ [ DebuggerStepThrough ]
96+ public static void Each < T > ( this IEnumerable source , Action < T > action )
97+ {
98+ foreach ( var item in source )
99+ action ( ( T ) item ) ;
100+ }
101+
102+ /// <summary>
103+ /// For shortcut with index, no side effects
104+ /// </summary>
105+ [ DebuggerStepThrough ]
106+ public static void EachIndex < T > ( this IEnumerable < T > source , Action < T , int > action )
107+ {
108+ var i = 0 ;
109+ Each ( source , item => action ( item , i ++ ) ) ;
110+ }
34111 }
35112}
0 commit comments