@@ -268,5 +268,122 @@ public static int Sum<T>(this IEnumerable<T> source, Func<T, int> selector)
268268
269269 return source . Select ( selector ) . Sum ( ) ;
270270 }
271+
272+ /// <summary>
273+ /// Returns the maximum element based on a given selector function.
274+ /// </summary>
275+ /// <typeparam name="TSource"></typeparam>
276+ /// <typeparam name="TKey"></typeparam>
277+ /// <param name="source"></param>
278+ /// <param name="selector"></param>
279+ /// <returns></returns>
280+ /// <exception cref="ArgumentNullException"></exception>
281+ public static TSource MaxBy < TSource , TKey > ( this IEnumerable < TSource > source , Func < TSource , TKey > selector )
282+ where TKey : IComparable < TKey >
283+ {
284+ if ( source == null ) throw new ArgumentNullException ( nameof ( source ) ) ;
285+ if ( selector == null ) throw new ArgumentNullException ( nameof ( selector ) ) ;
286+
287+ return source . Aggregate ( ( maxItem , nextItem ) => selector ( nextItem ) . CompareTo ( selector ( maxItem ) ) > 0 ? nextItem : maxItem ) ;
288+ }
289+
290+ /// <summary>
291+ /// Returns the minimum element based on a given selector function.
292+ /// </summary>
293+ /// <typeparam name="TSource"></typeparam>
294+ /// <typeparam name="TKey"></typeparam>
295+ /// <param name="source"></param>
296+ /// <param name="selector"></param>
297+ /// <returns></returns>
298+ /// <exception cref="ArgumentNullException"></exception>
299+ public static TSource MinBy < TSource , TKey > ( this IEnumerable < TSource > source , Func < TSource , TKey > selector )
300+ where TKey : IComparable < TKey >
301+ {
302+ if ( source == null ) throw new ArgumentNullException ( nameof ( source ) ) ;
303+ if ( selector == null ) throw new ArgumentNullException ( nameof ( selector ) ) ;
304+
305+ return source . Aggregate ( ( minItem , nextItem ) => selector ( nextItem ) . CompareTo ( selector ( minItem ) ) < 0 ? nextItem : minItem ) ;
306+ }
307+
308+ /// <summary>
309+ /// Finds the index of the first element that satisfies a given predicate.
310+ /// </summary>
311+ /// <typeparam name="T"></typeparam>
312+ /// <param name="source"></param>
313+ /// <param name="predicate"></param>
314+ /// <returns></returns>
315+ /// <exception cref="ArgumentNullException"></exception>
316+ public static int FindIndex < T > ( this IEnumerable < T > source , Func < T , bool > predicate )
317+ {
318+ if ( source == null ) throw new ArgumentNullException ( nameof ( source ) ) ;
319+ if ( predicate == null ) throw new ArgumentNullException ( nameof ( predicate ) ) ;
320+
321+ int index = 0 ;
322+ foreach ( var item in source )
323+ {
324+ if ( predicate ( item ) ) return index ;
325+ index ++ ;
326+ }
327+ return - 1 ;
328+ }
329+
330+ /// <summary>
331+ /// Checks if the source contains any of the specified items.
332+ /// </summary>
333+ /// <typeparam name="T"></typeparam>
334+ /// <param name="source"></param>
335+ /// <param name="items"></param>
336+ /// <returns></returns>
337+ /// <exception cref="ArgumentNullException"></exception>
338+ public static bool ContainsAny < T > ( this IEnumerable < T > source , params T [ ] items )
339+ {
340+ if ( source == null ) throw new ArgumentNullException ( nameof ( source ) ) ;
341+ if ( items == null ) throw new ArgumentNullException ( nameof ( items ) ) ;
342+
343+ var set = new HashSet < T > ( items ) ;
344+ return source . Any ( set . Contains ) ;
345+ }
346+
347+ /// <summary>
348+ /// Checks if the source contains all of the specified items.
349+ /// </summary>
350+ /// <typeparam name="T"></typeparam>
351+ /// <param name="source"></param>
352+ /// <param name="items"></param>
353+ /// <returns></returns>
354+ /// <exception cref="ArgumentNullException"></exception>
355+ public static bool ContainsAll < T > ( this IEnumerable < T > source , params T [ ] items )
356+ {
357+ if ( source == null ) throw new ArgumentNullException ( nameof ( source ) ) ;
358+ if ( items == null ) throw new ArgumentNullException ( nameof ( items ) ) ;
359+
360+ var set = new HashSet < T > ( source ) ;
361+ return items . All ( set . Contains ) ;
362+ }
363+
364+ /// <summary>
365+ /// Returns the median of a sequence of numbers.
366+ /// </summary>
367+ /// <param name="source"></param>
368+ /// <returns></returns>
369+ /// <exception cref="ArgumentNullException"></exception>
370+ public static double Median ( this IEnumerable < int > source )
371+ {
372+ if ( source == null ) throw new ArgumentNullException ( nameof ( source ) ) ;
373+
374+ var sortedList = source . OrderBy ( n => n ) . ToList ( ) ;
375+ int count = sortedList . Count ;
376+ if ( count == 0 )
377+ throw new InvalidOperationException ( "The source sequence is empty." ) ;
378+
379+ if ( count % 2 == 0 )
380+ {
381+ return ( sortedList [ count / 2 - 1 ] + sortedList [ count / 2 ] ) / 2.0 ;
382+ }
383+ else
384+ {
385+ return sortedList [ count / 2 ] ;
386+ }
387+ }
271388 }
272389}
0 commit comments