< Summary

Information
Class: SwiftCollections.SwiftExtensions
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Utility/SwiftExtensions.cs
Line coverage
98%
Covered lines: 55
Uncovered lines: 1
Coverable lines: 56
Total lines: 215
Line coverage: 98.2%
Branch coverage
96%
Covered branches: 27
Total branches: 28
Branch coverage: 96.4%
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%2275%
FromEnd(...)100%22100%
PopLast(...)100%11100%
SkipFromEnd()100%44100%
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)
 21        {
 39556622            for (int i = 0; i < array.Length; i++)
 19764023                array[i] = provider();
 14324            return array;
 25        }
 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)
 36        {
 837            for (int i = 0; i < array.Length; i++)
 338                array[i] = provider(i);
 139            return array;
 40        }
 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()
 51        {
 652            for (int i = 0; i < array.Length; i++)
 253                array[i] = new T();
 154            return array;
 55        }
 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)
 72        {
 573            if (array != null)
 74            {
 475                if (index < 0)
 76                {
 77                    // Support negative indices to access elements from the end
 278                    index = array.Length + index;
 79                }
 480                if (index >= 0 && index < array.Length)
 81                {
 282                    result = array[index];
 283                    return true;
 84                }
 85            }
 86
 387            result = default!;
 388            return false;
 89        }
 90
 91        /// <summary>
 92        /// An iterator that yields the elements of the source collection in a random order using the specified random n
 93        /// </summary>
 94        /// <typeparam name="T">The type of elements in the collection.</typeparam>
 95        /// <param name="source">The collection to shuffle.</param>
 96        /// <param name="rng">The random number generator to use for shuffling.</param>
 97        /// <returns>An iterator that yields the shuffled elements.</returns>
 98        public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
 99        {
 3100            SwiftThrowHelper.ThrowIfNull(source, nameof(source));
 2101            SwiftThrowHelper.ThrowIfNull(rng, nameof(rng));
 102
 1103            SwiftList<T> buffer = new(source);
 1104            int n = buffer.Count;
 7105            while (n > 0)
 106            {
 6107                int k = rng.Next(n);
 6108                n--;
 109                // Swap the selected element with the last unshuffled element
 6110                (buffer[k], buffer[n]) = (buffer[n], buffer[k]);
 6111                yield return buffer[n];
 112            }
 1113        }
 114
 115        /// <summary>
 116        /// Shuffles the elements of the list in place using the specified random number generator.
 117        /// </summary>
 118        /// <typeparam name="T">The type of elements in the list.</typeparam>
 119        /// <param name="list">The list to shuffle.</param>
 120        /// <param name="rng">The random number generator to use for shuffling.</param>
 121        public static void ShuffleInPlace<T>(this IList<T> list, Random rng)
 122        {
 3123            SwiftThrowHelper.ThrowIfNull(list, nameof(list));
 2124            SwiftThrowHelper.ThrowIfNull(rng, nameof(rng));
 125
 1126            int n = list.Count;
 6127            while (n > 1)
 128            {
 5129                n--;
 5130                int k = rng.Next(n + 1);
 5131                (list[n], list[k]) = (list[k], list[n]);
 132            }
 1133        }
 134
 135        /// <summary>
 136        /// Determines whether a sequence contains any elements.
 137        /// </summary>
 138        /// <typeparam name="T"></typeparam>
 139        /// <param name="source"> The <see cref="IEnumerable{T}"/> to check for emptiness.</param>
 140        /// <returns>
 141        /// true if the source sequence contains any elements; otherwise, false.
 142        /// </returns>
 143        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 144        public static bool IsPopulated<T>(this IEnumerable<T> source)
 145        {
 4146            SwiftThrowHelper.ThrowIfNull(source, nameof(source));
 3147            using IEnumerator<T> enumerator = source.GetEnumerator();
 3148            return enumerator.MoveNext();
 3149        }
 150
 151        /// <summary>
 152        /// Determines whether the collection is not null and contains any elements.
 153        /// </summary>
 154        /// <typeparam name="T">The type of elements in the collection.</typeparam>
 155        /// <param name="source">The collection to check.</param>
 156        /// <returns>
 157        /// True if the collection is not null and contains at least one element; otherwise, false.
 158        /// </returns>
 159        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2160        public static bool IsPopulatedSafe<T>(this IEnumerable<T> source) => source != null && source.IsPopulated();
 161
 162        /// <summary>
 163        /// Gets the element at the specified index from the end (1-based).
 164        /// For example, FromEnd(1) returns the last item, FromEnd(2) returns second-to-last.
 165        /// </summary>
 166        public static T FromEnd<T>(this IEnumerable<T> source, int reverseIndex)
 167        {
 3168            if (source is SwiftList<T> swift)
 0169                return swift.FromEnd(reverseIndex);
 170
 171            // fallback for generic IEnumerable
 3172            var buffer = new SwiftList<T>(source);
 3173            return buffer.FromEnd(reverseIndex);
 174        }
 175
 176        /// <summary>
 177        /// Gets the element at the specified index from the end (1-based) from SwiftList.
 178        /// </summary>
 179        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 180        public static T FromEnd<T>(this SwiftList<T> list, int reverseIndex)
 181        {
 6182            SwiftThrowHelper.ThrowIfArgumentOutOfRange(reverseIndex <= 0 || reverseIndex > list.Count, reverseIndex, nam
 4183            return list[^reverseIndex];
 184        }
 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)
 196        {
 5197            SwiftThrowHelper.ThrowIfNull(source, nameof(source));
 4198            SwiftThrowHelper.ThrowIfNegative(count, nameof(count));
 199
 3200            SwiftQueue<T> buffer = new();
 201
 26202            foreach (T item in source)
 203            {
 10204                buffer.Enqueue(item);
 10205                if (buffer.Count > count)
 6206                    yield return buffer.Dequeue();
 207            }
 3208        }
 209
 210        /// <summary>
 211        /// Returns the second-to-last item in the sequence.
 212        /// </summary>
 1213        public static T SecondToLast<T>(this IEnumerable<T> source) => source.FromEnd(2);
 214    }
 215}