< Summary

Information
Class: SwiftCollections.SwiftExtensions
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Utility/SwiftExtensions.cs
Line coverage
98%
Covered lines: 85
Uncovered lines: 1
Coverable lines: 86
Total lines: 217
Line coverage: 98.8%
Branch coverage
97%
Covered branches: 33
Total branches: 34
Branch coverage: 97%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Populate(...)100%22100%
Populate(...)100%22100%
Populate(...)100%22100%
TryIndex(...)100%88100%
Shuffle()100%22100%
ShuffleInPlace(...)100%22100%
IsPopulated(...)100%11100%
IsPopulatedSafe(...)100%22100%
FromEnd(...)50%2283.33%
FromEnd(...)100%44100%
PopLast(...)100%11100%
SkipFromEnd()100%88100%
SecondToLast(...)100%11100%

File(s)

/home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Utility/SwiftExtensions.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Runtime.CompilerServices;
 4
 5namespace SwiftCollections
 6{
 7    /// <summary>
 8    /// Provides extension methods for collection manipulation and utility functions.
 9    /// </summary>
 10    public static class SwiftExtensions
 11    {
 12        /// <summary>
 13        /// Populates an array with values generated by a specified provider function.
 14        /// </summary>
 15        /// <typeparam name="T">The type of the elements in the array.</typeparam>
 16        /// <param name="array">The array to populate.</param>
 17        /// <param name="provider">A function that generates a value for each element in the array.</param>
 18        /// <returns>The populated array.</returns>
 19        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 20        public static T[] Populate<T>(this T[] array, Func<T> provider)
 18121        {
 45604022            for (int i = 0; i < array.Length; i++)
 22783923                array[i] = provider();
 18124            return array;
 18125        }
 26
 27        /// <summary>
 28        /// Populates an array with values generated by a provider function that accepts the current index.
 29        /// </summary>
 30        /// <typeparam name="T">The type of the elements in the array.</typeparam>
 31        /// <param name="array">The array to populate.</param>
 32        /// <param name="provider">A function that generates a value for each element based on its index.</param>
 33        /// <returns>The populated array.</returns>
 34        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 35        public static T[] Populate<T>(this T[] array, Func<int, T> provider)
 136        {
 837            for (int i = 0; i < array.Length; i++)
 338                array[i] = provider(i);
 139            return array;
 140        }
 41
 42        /// <summary>
 43        /// Populates an array with new instances of the specified type.
 44        /// The type must have a parameterless constructor.
 45        /// </summary>
 46        /// <typeparam name="T">The type of the elements in the array.</typeparam>
 47        /// <param name="array">The array to populate.</param>
 48        /// <returns>The populated array.</returns>
 49        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 50        public static T[] Populate<T>(this T[] array) where T : new()
 151        {
 652            for (int i = 0; i < array.Length; i++)
 253                array[i] = new T();
 154            return array;
 155        }
 56
 57        /// <summary>
 58        /// Attempts to retrieve an element from the array at the specified index.
 59        /// Returns true if the index is valid and the element is retrieved; otherwise, returns false.
 60        /// </summary>
 61        /// <typeparam name="T">The type of elements in the array.</typeparam>
 62        /// <param name="array">The array from which to retrieve the element.</param>
 63        /// <param name="index">The index of the element to retrieve.</param>
 64        /// <param name="result">
 65        /// When this method returns, contains the element at the specified index if the index is valid;
 66        /// otherwise, the default value for the type of the element.
 67        /// </param>
 68        /// <returns>
 69        /// True if the element at the specified index was retrieved successfully; otherwise, false.
 70        /// </returns>
 71        public static bool TryIndex<T>(this T[] array, int index, out T result)
 572        {
 573            if (array != null)
 474            {
 475                if (index < 0)
 276                {
 77                    // Support negative indices to access elements from the end
 278                    index = array.Length + index;
 279                }
 480                if (index >= 0 && index < array.Length)
 281                {
 282                    result = array[index];
 283                    return true;
 84                }
 285            }
 386            result = default;
 387            return false;
 588        }
 89
 90        /// <summary>
 91        /// An iterator that yields the elements of the source collection in a random order using the specified random n
 92        /// </summary>
 93        /// <typeparam name="T">The type of elements in the collection.</typeparam>
 94        /// <param name="source">The collection to shuffle.</param>
 95        /// <param name="rng">The random number generator to use for shuffling.</param>
 96        /// <returns>An iterator that yields the shuffled elements.</returns>
 97        public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
 398        {
 399            SwiftThrowHelper.ThrowIfNull(source, nameof(source));
 2100            SwiftThrowHelper.ThrowIfNull(rng, nameof(rng));
 101
 1102            SwiftList<T> buffer = new SwiftList<T>(source);
 1103            int n = buffer.Count;
 7104            while (n > 0)
 6105            {
 6106                int k = rng.Next(n);
 6107                n--;
 108                // Swap the selected element with the last unshuffled element
 6109                (buffer[k], buffer[n]) = (buffer[n], buffer[k]);
 6110                yield return buffer[n];
 6111            }
 1112        }
 113
 114        /// <summary>
 115        /// Shuffles the elements of the list in place using the specified random number generator.
 116        /// </summary>
 117        /// <typeparam name="T">The type of elements in the list.</typeparam>
 118        /// <param name="list">The list to shuffle.</param>
 119        /// <param name="rng">The random number generator to use for shuffling.</param>
 120        public static void ShuffleInPlace<T>(this IList<T> list, Random rng)
 3121        {
 3122            SwiftThrowHelper.ThrowIfNull(list, nameof(list));
 2123            SwiftThrowHelper.ThrowIfNull(rng, nameof(rng));
 124
 1125            int n = list.Count;
 6126            while (n > 1)
 5127            {
 5128                n--;
 5129                int k = rng.Next(n + 1);
 5130                (list[n], list[k]) = (list[k], list[n]);
 5131            }
 1132        }
 133
 134        /// <summary>
 135        /// Determines whether a sequence contains any elements.
 136        /// </summary>
 137        /// <typeparam name="T"></typeparam>
 138        /// <param name="source"> The <see cref="IEnumerable{T}"/> to check for emptiness.</param>
 139        /// <returns>
 140        /// true if the source sequence contains any elements; otherwise, false.
 141        /// </returns>
 142        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 143        public static bool IsPopulated<T>(this IEnumerable<T> source)
 4144        {
 4145            SwiftThrowHelper.ThrowIfNull(source, nameof(source));
 3146            using IEnumerator<T> enumerator = source.GetEnumerator();
 3147            return enumerator.MoveNext();
 3148        }
 149
 150        /// <summary>
 151        /// Determines whether the collection is not null and contains any elements.
 152        /// </summary>
 153        /// <typeparam name="T">The type of elements in the collection.</typeparam>
 154        /// <param name="source">The collection to check.</param>
 155        /// <returns>
 156        /// True if the collection is not null and contains at least one element; otherwise, false.
 157        /// </returns>
 158        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2159        public static bool IsPopulatedSafe<T>(this IEnumerable<T> source) => source != null && source.IsPopulated();
 160
 161        /// <summary>
 162        /// Gets the element at the specified index from the end (1-based).
 163        /// For example, FromEnd(1) returns the last item, FromEnd(2) returns second-to-last.
 164        /// </summary>
 165        public static T FromEnd<T>(this IEnumerable<T> source, int reverseIndex)
 3166        {
 3167            if (source is SwiftList<T> swift)
 0168                return swift.FromEnd(reverseIndex);
 169
 170            // fallback for generic IEnumerable
 3171            var buffer = new SwiftList<T>(source);
 3172            return buffer.FromEnd(reverseIndex);
 3173        }
 174
 175        /// <summary>
 176        /// Gets the element at the specified index from the end (1-based) from SwiftList.
 177        /// </summary>
 178        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 179        public static T FromEnd<T>(this SwiftList<T> list, int reverseIndex)
 6180        {
 6181            if (reverseIndex <= 0 || reverseIndex > list.Count)
 2182                throw new ArgumentOutOfRangeException(nameof(reverseIndex));
 4183            return list[^reverseIndex];
 4184        }
 185
 186        /// <summary>
 187        /// Returns the last item in the sequence.
 188        /// </summary>
 189        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1190        public static T PopLast<T>(this IEnumerable<T> source) => source.FromEnd(1);
 191
 192        /// <summary>
 193        /// Bypasses a specified number of elements from the end and then returns the remaining elements.
 194        /// </summary>
 195        public static IEnumerable<T> SkipFromEnd<T>(this IEnumerable<T> source, int count)
 5196        {
 5197            if (source == null)
 1198                throw new ArgumentNullException(nameof(source));
 4199            if (count < 0)
 1200                throw new ArgumentOutOfRangeException(nameof(count));
 201
 3202            SwiftQueue<T> buffer = new();
 203
 29204            foreach (T item in source)
 10205            {
 10206                buffer.Enqueue(item);
 10207                if (buffer.Count > count)
 6208                    yield return buffer.Dequeue();
 10209            }
 3210        }
 211
 212        /// <summary>
 213        /// Returns the second-to-last item in the sequence.
 214        /// </summary>
 1215        public static T SecondToLast<T>(this IEnumerable<T> source) => source.FromEnd(2);
 216    }
 217}