I just added a flatten method of my SimpleTsLinq library today!
The Github repo is at:
The Npm page is at:
This method can flatten multiple arrays at desired depth (defaults to Infinity) and each array itself may have arbitrary depth.
The end result is that the multiple (nested arrays) are returned as a flat, single array. Much similar to SelectMany in Linq!
First I added the method to generic interface Array below
if (!Array.prototype.Flatten) {
Array.prototype.Flatten = function <T>(otherArrays: T[][] = null, depth = Infinity) {
let flattenedArrayOfThis = [...flatten(this, depth)];
if (otherArrays == null || otherArrays == undefined) {
return flattenedArrayOfThis;
}
return [...flattenedArrayOfThis, ...flatten(otherArrays, depth)];
}
}
function* flatten(array, depth) {
if (depth === undefined) {
depth = 1;
}
for (const item of array) {
if (Array.isArray(item) && depth > 0) {
yield* flatten(item, depth - 1);
} else {
yield item;
}
}
}
The implementation uses a generator (identified by the * suffix) method which is recursively called if we have an array within an array
Two tests below are run in Karma to test it out.
it('can flatten multiple arrays into a single array', () => {
let oneArray = [1, 2, [3, 3]];
let anotherArray = [4, [4, 5], 6];
let thirdArray = [7, 7, [7, 7]];
let threeArrays = [oneArray, anotherArray, thirdArray];
let flattenedArrays = oneArray.Flatten([anotherArray, thirdArray], Infinity);
let isEqualInContentToExpectedFlattenedArray = flattenedArrays.SequenceEqual([1, 2, 3, 3, 4, 4, 5, 6, 7, 7, 7, 7]);
expect(isEqualInContentToExpectedFlattenedArray).toBe(true);
});
it('can flatten one deep array into a single array', () => {
let oneArray = [1, 2, [3, 3]];
let flattenedArrays = oneArray.Flatten(null, 1);
let isEqualInContentToExpectedFlattenedArray = flattenedArrays.SequenceEqual([1, 2, 3, 3]);
expect(isEqualInContentToExpectedFlattenedArray).toBe(true);
});