- Developed using Visual Studio Community and .NET Framework 4.7.1.
- Compatible with all types of arrays.
- Generics was used to define the return type.
- Unit testing done through MSTest.
Created
July 14, 2018 14:46
-
-
Save jonasraoni/5ac06c17d096e2ac4117ca03a2f9244c to your computer and use it in GitHub Desktop.
Flatten Array in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
/// <summary> | |
/// Extends the Array with the Flatten method | |
/// </summary> | |
public static class Flattener { | |
/// <summary> | |
/// Given a N-dimensional array, flattens it into a new one-dimensional array without modifying the elements' order | |
/// </summary> | |
/// <typeparam name="T">The type of elements contained in the array</typeparam> | |
/// <param name="data">The input array</param> | |
/// <returns>A flattened array</returns> | |
public static T[] Flatten<T>(this Array data) { | |
var list = new List<T>(); | |
var stack = new Stack<IEnumerator>(); | |
stack.Push(data.GetEnumerator()); | |
do { | |
for (var iterator = stack.Pop(); iterator.MoveNext();) { | |
if (iterator.Current is Array) { | |
stack.Push(iterator); | |
iterator = (iterator.Current as IEnumerable).GetEnumerator(); | |
} | |
else | |
list.Add((T)iterator.Current); | |
} | |
} | |
while (stack.Count > 0); | |
return list.ToArray(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Microsoft.VisualStudio.TestTools.UnitTesting; | |
namespace FlattenerTests { | |
[TestClass] | |
public class FlattenerTests { | |
[TestMethod] | |
[Description("Should return a one-dimensional with the right data type")] | |
public void Flatten_ReturnsRightDataType() { | |
Assert.IsInstanceOfType(new int[,,,,] { }.Flatten<int>(), typeof(int[])); | |
Assert.IsInstanceOfType(new char[][] { }.Flatten<char>(), typeof(char[])); | |
Assert.IsInstanceOfType(new string[] { }.Flatten<string>(), typeof(string[])); | |
} | |
[TestMethod] | |
[Description("The elements' order should be kept for multidimensional/jagged arrays")] | |
public void Flatten_MultidimensionalArray_KeepsElementsOrder() { | |
var intArray = new[, ,] { { { 1, 1 }, { 2, 3 } } }; | |
CollectionAssert.AreEqual(intArray.Flatten<int>(), new[] { 1, 1, 2, 3 }); | |
var dynamicJaggedArray = new dynamic[] { 1, new dynamic[] { "2", 3, new { prop = 123 } } }; | |
CollectionAssert.AreEqual(dynamicJaggedArray.Flatten<dynamic>(), new dynamic[] { 1, "2", 3, new { prop = 123 } }); | |
var intJaggedArray = new int[][] { new int[] { 1, 1 }, new int[] { 2, 3, 4 } }; | |
CollectionAssert.AreEqual(intJaggedArray.Flatten<int>(), new[] { 1, 1, 2, 3, 4 }); | |
var stringJaggedArray = new dynamic[] { new[] { "a" }, new dynamic[] { "b", new[] { "c" } } }; | |
CollectionAssert.AreEqual(stringJaggedArray.Flatten<string>(), new[] { "a", "b", "c" }); | |
} | |
[TestMethod] | |
[Description("An empty array should return an empty array")] | |
public void Flatten_EmptyArray_ReturnsEmptyArray() { | |
var jaggedIntArray = new int[][][] { }; | |
Assert.AreEqual(jaggedIntArray.Flatten<int>().Length, 0); | |
var intArray = new int[,,] { }; | |
Assert.AreEqual(intArray.Flatten<int>().Length, 0); | |
} | |
[TestMethod] | |
[Description("Flattening an array of a given type into a different type should fail")] | |
public void Flatten_IncompatibleType_Fail() { | |
var dynamicArray = new dynamic[] { 1, "2", 3, new { prop = 123 } }; | |
Assert.ThrowsException<InvalidCastException>(() => dynamicArray.Flatten<string>()); | |
var shortArray = new short[] { 1, 2, 3 }; | |
Assert.ThrowsException<InvalidCastException>(() => shortArray.Flatten<int>()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment