@@ -268,5 +268,122 @@ public static int Sum<T>(this IEnumerable<T> source, Func<T, int> selector)
268
268
269
269
return source . Select ( selector ) . Sum ( ) ;
270
270
}
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
+ }
271
388
}
272
389
}
0 commit comments