2024-06-26 17:59:28 +12:00
using System.Security.Cryptography ;
2024-05-18 00:08:52 +12:00
namespace Ellie.Common ;
public static class EnumerableExtensions
{
/// <summary>
/// Concatenates the members of a collection, using the specified separator between each member.
/// </summary>
/// <param name="data">Collection to join</param>
/// <param name="separator">
/// The character to use as a separator. separator is included in the returned string only if
/// values has more than one element.
/// </param>
/// <param name="func">Optional transformation to apply to each element before concatenation.</param>
/// <typeparam name="T">The type of the members of values.</typeparam>
/// <returns>
/// A string that consists of the members of values delimited by the separator character. -or- Empty if values has
/// no elements.
/// </returns>
public static string Join < T > ( this IEnumerable < T > data , char separator , Func < T , string > ? func = null )
= > string . Join ( separator , data . Select ( func ? ? ( x = > x ? . ToString ( ) ? ? string . Empty ) ) ) ;
/// <summary>
/// Concatenates the members of a collection, using the specified separator between each member.
/// </summary>
/// <param name="data">Collection to join</param>
/// <param name="separator">
/// The string to use as a separator.separator is included in the returned string only if values
/// has more than one element.
/// </param>
/// <param name="func">Optional transformation to apply to each element before concatenation.</param>
/// <typeparam name="T">The type of the members of values.</typeparam>
/// <returns>
/// A string that consists of the members of values delimited by the separator character. -or- Empty if values has
/// no elements.
/// </returns>
public static string Join < T > ( this IEnumerable < T > data , string separator , Func < T , string > ? func = null )
= > string . Join ( separator , data . Select ( func ? ? ( x = > x ? . ToString ( ) ? ? string . Empty ) ) ) ;
2024-06-26 17:59:28 +12:00
2024-05-18 00:08:52 +12:00
/// <summary>
/// Randomize element order by performing the Fisher-Yates shuffle
/// </summary>
/// <typeparam name="T">Item type</typeparam>
/// <param name="items">Items to shuffle</param>
public static IReadOnlyList < T > Shuffle < T > ( this IEnumerable < T > items )
{
var list = items . ToArray ( ) ;
var n = list . Length ;
while ( n - - > 1 )
{
var k = RandomNumberGenerator . GetInt32 ( n ) ;
( list [ k ] , list [ n ] ) = ( list [ n ] , list [ k ] ) ;
}
return list ;
}
/// <summary>
/// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}" /> class
/// that contains elements copied from the specified <see cref="IEnumerable{T}" />
/// has the default concurrency level, has the default initial capacity,
/// and uses the default comparer for the key type.
/// </summary>
/// <param name="dict">
/// The <see cref="IEnumerable{T}" /> whose elements are copied to the new
/// <see cref="ConcurrentDictionary{TKey,TValue}" />.
/// </param>
/// <returns>A new instance of the <see cref="ConcurrentDictionary{TKey,TValue}" /> class</returns>
public static ConcurrentDictionary < TKey , TValue > ToConcurrent < TKey , TValue > (
this IEnumerable < KeyValuePair < TKey , TValue > > dict )
where TKey : notnull
= > new ( dict ) ;
2024-09-12 15:44:35 +12:00
/// <summary>
/// Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}" /> class
/// that contains elements copied from the specified <see cref="IEnumerable{T}" />
/// has the default concurrency level, has the default initial capacity,
/// and uses the default comparer for the key type.
/// </summary>
/// <param name="dict">
/// The <see cref="IEnumerable{T}" /> whose elements are copied to the new
/// <see cref="ConcurrentDictionary{TKey,TValue}" />.
/// </param>
/// <returns>A new instance of the <see cref="ConcurrentDictionary{TKey,TValue}" /> class</returns>
public static ConcurrentHashSet < TValue > ToConcurrentSet < TValue > (
this IReadOnlyCollection < TValue > dict )
where TValue : notnull
= > new ( dict ) ;
2024-05-18 00:08:52 +12:00
public static IndexedCollection < T > ToIndexed < T > ( this IEnumerable < T > enumerable )
where T : class , IIndexed
= > new ( enumerable ) ;
/// <summary>
/// Creates a task that will complete when all of the <see cref="Task{TResult}" /> objects in an enumerable
/// collection have completed
/// </summary>
/// <param name="tasks">The tasks to wait on for completion.</param>
/// <typeparam name="TResult">The type of the completed task.</typeparam>
/// <returns>A task that represents the completion of all of the supplied tasks.</returns>
public static Task < TResult [ ] > WhenAll < TResult > ( this IEnumerable < Task < TResult > > tasks )
= > Task . WhenAll ( tasks ) ;
/// <summary>
/// Creates a task that will complete when all of the <see cref="Task" /> objects in an enumerable
/// collection have completed
/// </summary>
/// <param name="tasks">The tasks to wait on for completion.</param>
/// <returns>A task that represents the completion of all of the supplied tasks.</returns>
public static Task WhenAll ( this IEnumerable < Task > tasks )
= > Task . WhenAll ( tasks ) ;
}