Skip to content

Commit

Permalink
Add methods for multi dimensional arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim-Maes committed Dec 16, 2023
1 parent 08ae683 commit 109f279
Show file tree
Hide file tree
Showing 4 changed files with 321 additions and 1 deletion.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,25 @@ Or just copy whatever you need from this repository :)
|`ToFrequencyMap`| Creates a frequency map (count of each element).|
|`Variance`| Calculates the variance of the array elements.|

## Multi Dimensional Array methods

## Generic Multi Dimensional Array methods

| Name | Description |
|-------------------------------------|----------------------------------------------------------------------|
| `AllEqual<T>()` | Checks if all elements in a multi-dimensional array are identical. |
| `Contains<T>()` | Checks if the multi-dimensional array contains a specific element. |
| `CountOf<T>()` | Counts occurrences of a specific item in the multi-dimensional array.|
| `DeepCopy<T>()` | Creates a deep copy of the multi-dimensional array. |
| `Fill<T>()` | Fills the multi-dimensional array with a specific value. |
| `FindFirst<T>()` | Finds the first occurrence of an element that matches a condition. |
| `Flatten<T>()` | Flattens a multi-dimensional array into a single-dimensional array. |
| `ForEach<T>()` | Iterates over each element in a multi-dimensional array and executes the provided action. |
| `GetColumn<T>()` | Retrieves a specific column from a multi-dimensional array. |
| `GetRow<T>()` | Retrieves a specific row from a multi-dimensional array. |
| `Rotate90DegreesClockwise<T>()` | Rotates the array 90 degrees clockwise. |
| `Transpose<T>()` | Transposes a two-dimensional array. |

## License

[MIT](https://opensource.org/licenses/MIT)
116 changes: 116 additions & 0 deletions src/ArrayExtensions.Tests/MultiDimensionalArrayTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using FluentAssertions;
using Xunit;

namespace ArrayExtensions.Tests;

public class MultiDimensionalArrayTests
{
[Fact]
public void ForEach_ShouldExecuteActionForEachElement()
{
var array = new[,] { { 1, 2 }, { 3, 4 } };
int sum = 0;
array.ForEach(x => sum += x);
sum.Should().Be(10);
}

[Fact]
public void Transpose_ShouldTransposeArray()
{
var array = new[,] { { 1, 2 }, { 3, 4 } };
var transposed = array.Transpose();
var expected = new[,] { { 1, 3 }, { 2, 4 } };
transposed.Should().BeEquivalentTo(expected);
}

[Fact]
public void Flatten_ShouldConvertToSingleDimensionalArray()
{
var array = new[,] { { 1, 2 }, { 3, 4 } };
var flattened = array.Flatten();
var expected = new[] { 1, 2, 3, 4 };
flattened.Should().Equal(expected);
}

[Fact]
public void DeepCopy_ShouldCreateSeparateArray()
{
var array = new[,] { { "a", "b" }, { "c", "d" } };
var copy = array.DeepCopy();
copy.Should().NotBeSameAs(array);
copy.Should().BeEquivalentTo(array);
}

[Fact]
public void AllEqual_WithIdenticalElements_ShouldReturnTrue()
{
var array = new[,] { { 1, 1 }, { 1, 1 } };
var result = array.AllEqual();
result.Should().BeTrue();
}

[Fact]
public void CountOf_SpecificValue_ShouldReturnCount()
{
var array = new[,] { { 1, 2 }, { 1, 2 } };
var count = array.CountOf(1);
count.Should().Be(2);
}

[Fact]
public void Fill_ShouldFillArrayWithSpecifiedValue()
{
var array = new int[2, 2];
array.Fill(5);
array.Cast<int>().Should().AllBeEquivalentTo(5);
}

[Fact]
public void FindFirst_MatchingPredicate_ShouldReturnCoordinates()
{
var array = new[,] { { 1, 2 }, { 3, 4 } };
var result = array.FindFirst(x => x == 3);
result.Should().Be((1, 0));
}

[Fact]
public void FindFirst_NonMatchingPredicate_ShouldReturnNull()
{
var array = new[,] { { 1, 2 }, { 3, 4 } };
var result = array.FindFirst(x => x == 5);
result.Should().BeNull();
}

[Fact]
public void GetRow_ShouldReturnSpecificRow()
{
var array = new[,] { { 1, 2 }, { 3, 4 } };
var row = array.GetRow(1);
row.Should().Equal(3, 4);
}

[Fact]
public void GetColumn_ShouldReturnSpecificColumn()
{
var array = new[,] { { 1, 2 }, { 3, 4 } };
var column = array.GetColumn(1);
column.Should().Equal(2, 4);
}

[Fact]
public void Rotate90DegreesClockwise_ShouldRotateArray()
{
var array = new[,] { { 1, 2 }, { 3, 4 } };
var rotated = array.Rotate90DegreesClockwise();
var expected = new[,] { { 3, 1 }, { 4, 2 } };
rotated.Should().BeEquivalentTo(expected);
}

[Fact]
public void Contains_ExistingElement_ShouldReturnTrue()
{
var array = new[,] { { 1, 2 }, { 3, 4 } };
var result = array.Contains(3);
result.Should().BeTrue();
}
}
2 changes: 1 addition & 1 deletion src/ArrayExtensions/ArrayExtensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<PackageProjectUrl>https://www.github.com/Tim-Maes/ArrayExtensions</PackageProjectUrl>
<RepositoryUrl>https://www.github.com/Tim-Maes/ArrayExtensions</RepositoryUrl>
<PackageTags>array, extensions</PackageTags>
<Version>1.2.7</Version>
<Version>1.3.0</Version>
<EnablePackageValidation>true</EnablePackageValidation>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
Expand Down
185 changes: 185 additions & 0 deletions src/ArrayExtensions/MultiDimensionalArrayExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
namespace ArrayExtensions;

public static class MultiDimensionalArrayExtensions
{ /// <summary>
/// Iterates over each element in a multi-dimensional array and executes the provided action.
/// </summary>
public static void ForEach<T>(this T[,] array, Action<T> action)
{
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
action(array[i, j]);
}
}
}

/// <summary>
/// Transposes a two-dimensional array.
/// </summary>
public static T[,] Transpose<T>(this T[,] array)
{
var rows = array.GetLength(0);
var columns = array.GetLength(1);
var result = new T[columns, rows];

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
result[j, i] = array[i, j];
}
}

return result;
}

/// <summary>
/// Flattens a multi-dimensional array into a single-dimensional array.
/// </summary>
public static T[] Flatten<T>(this T[,] array)
{
var rows = array.GetLength(0);
var columns = array.GetLength(1);
var result = new T[rows * columns];
int index = 0;

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
result[index++] = array[i, j];
}
}

return result;
}

/// <summary>
/// Creates a deep copy of the multi-dimensional array.
/// Note: Elements in the array must implement the ICloneable interface.
/// </summary>
public static T[,] DeepCopy<T>(this T[,] array) where T : ICloneable
{
var rows = array.GetLength(0);
var columns = array.GetLength(1);
var result = new T[rows, columns];

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
result[i, j] = (T)array[i, j].Clone();
}
}

return result;
}

/// <summary>
/// Checks if all elements in the multi-dimensional array are equal.
/// </summary>
public static bool AllEqual<T>(this T[,] array)
{
var first = array[0, 0];
return array.Cast<T>().All(element => EqualityComparer<T>.Default.Equals(element, first));
}

/// <summary>
/// Counts occurrences of a specific item in the multi-dimensional array.
/// </summary>
public static int CountOf<T>(this T[,] array, T item) where T : IEquatable<T>
{
return array.Cast<T>().Count(x => x.Equals(item));
}

/// <summary>
/// Fills the multi-dimensional array with a specific value.
/// </summary>
public static void Fill<T>(this T[,] array, T value)
{
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
array[i, j] = value;
}
}
}

/// <summary>
/// Finds the first occurrence of an element that matches a condition.
/// </summary>
public static (int, int)? FindFirst<T>(this T[,] array, Predicate<T> match)
{
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
if (match(array[i, j]))
{
return (i, j);
}
}
}

return null;
}

/// <summary>
/// Retrieves a specific row from a multi-dimensional array.
/// </summary>
public static T[] GetRow<T>(this T[,] array, int row)
{
var rowLength = array.GetLength(1);
var result = new T[rowLength];
for (int i = 0; i < rowLength; i++)
{
result[i] = array[row, i];
}
return result;
}

/// <summary>
/// Retrieves a specific column from a multi-dimensional array.
/// </summary>
public static T[] GetColumn<T>(this T[,] array, int column)
{
var columnLength = array.GetLength(0);
var result = new T[columnLength];
for (int i = 0; i < columnLength; i++)
{
result[i] = array[i, column];
}
return result;
}

/// <summary>
/// Rotates the array 90 degrees clockwise.
/// </summary>
public static T[,] Rotate90DegreesClockwise<T>(this T[,] array)
{
var rows = array.GetLength(0);
var columns = array.GetLength(1);
var result = new T[columns, rows];

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
result[j, rows - 1 - i] = array[i, j];
}
}

return result;
}

/// <summary>
/// Checks if the multi-dimensional array contains a specific element.
/// </summary>
public static bool Contains<T>(this T[,] array, T item) where T : IEquatable<T>
{
return array.Cast<T>().Any(x => x.Equals(item));
}
}

0 comments on commit 109f279

Please sign in to comment.