// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; namespace Microsoft.Toolkit.Extensions { /// /// Helpers for working with arrays. /// public static class ArrayExtensions { /// /// Fills elements of a rectangular array at the given position and size to a specific value. /// Ranges given will fill in as many elements as possible, ignoring positions outside the bounds of the array. /// /// The element type of the array. /// The source array. /// Value to fill with. /// Row to start on (inclusive, zero-index). /// Column to start on (inclusive, zero-index). /// Positive width of area to fill. /// Positive height of area to fill. public static void Fill(this T[,] array, T value, int row, int col, int width, int height) { for (int r = row; r < row + height; r++) { for (int c = col; c < col + width; c++) { if (r >= 0 && c >= 0 && r < array.GetLength(0) && c < array.GetLength(1)) { array[r, c] = value; } } } } /// /// Yields a row from a rectangular array. /// /// The element type of the array. /// The source array. /// Row record to retrieve, 0-based index. /// Yielded row. public static IEnumerable GetRow(this T[,] rectarray, int row) { if (row < 0 || row >= rectarray.GetLength(0)) { throw new ArgumentOutOfRangeException(nameof(row)); } for (int c = 0; c < rectarray.GetLength(1); c++) { yield return rectarray[row, c]; } } /// /// Yields a column from a rectangular array. /// /// The element type of the array. /// The source array. /// Column record to retrieve, 0-based index. /// Yielded column. public static IEnumerable GetColumn(this T[,] rectarray, int column) { if (column < 0 || column >= rectarray.GetLength(1)) { throw new ArgumentOutOfRangeException(nameof(column)); } for (int r = 0; r < rectarray.GetLength(0); r++) { yield return rectarray[r, column]; } } /// /// Yields a column from a jagged array. /// An exception will be thrown if the column is out of bounds, and return default in places where there are no elements from inner arrays. /// Note: There is no equivalent GetRow method, as you can use array[row] to retrieve. /// /// The element type of the array. /// The source array. /// Column record to retrieve, 0-based index. /// Yielded enumerable of column elements for given column, and default values for smaller inner arrays. public static IEnumerable GetColumn(this T[][] rectarray, int column) { if (column < 0 || column >= rectarray.Max(array => array.Length)) { throw new ArgumentOutOfRangeException(nameof(column)); } for (int r = 0; r < rectarray.GetLength(0); r++) { if (column >= rectarray[r].Length) { yield return default(T); continue; } yield return rectarray[r][column]; } } /// /// Returns a simple string representation of an array. /// /// The element type of the array. /// The source array. /// String representation of the array. public static string ToArrayString(this T[] array) { return "[" + string.Join(",\t", array) + "]"; } /// /// Returns a simple string representation of a jagged array. /// /// The element type of the array. /// The source array. /// String representation of the array. public static string ToArrayString(this T[][] mdarray) { string[] inner = new string[mdarray.GetLength(0)]; for (int r = 0; r < mdarray.GetLength(0); r++) { inner[r] = string.Join(",\t", mdarray[r]); } return "[[" + string.Join("]," + Environment.NewLine + " [", inner) + "]]"; } /// /// Returns a simple string representation of a rectangular array. /// /// The element type of the array. /// The source array. /// String representation of the array. public static string ToArrayString(this T[,] rectarray) { string[] inner = new string[rectarray.GetLength(0)]; for (int r = 0; r < rectarray.GetLength(0); r++) { inner[r] = string.Join(",\t", rectarray.GetRow(r)); } return "[[" + string.Join("]," + Environment.NewLine + " [", inner) + "]]"; } } }