Skip to content

Commit 86fc17d

Browse files
committed
added option to flatten arrays with homogeneous size
1 parent 8695764 commit 86fc17d

File tree

2 files changed

+41
-17
lines changed

2 files changed

+41
-17
lines changed

src/function/matrix/flatten.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { flatten as flattenArray } from '../../utils/array.js'
1+
import { flatten as flattenArray, arraySize, validate } from '../../utils/array.js'
22
import { factory } from '../../utils/factory.js'
33

44
const name = 'flatten'
@@ -26,13 +26,17 @@ export const createFlatten = /* #__PURE__ */ factory(name, dependencies, ({ type
2626
*/
2727
return typed(name, {
2828
Array: function (x) {
29-
return flattenArray(x)
29+
try {
30+
return flattenArray(x, validate(x, arraySize(x)))
31+
} catch {
32+
return flattenArray(x)
33+
}
3034
},
3135

3236
Matrix: function (x) {
3337
// Return the same matrix type as x (Dense or Sparse Matrix)
3438
// Return the same data type as x
35-
return x.create(flattenArray(x.toArray()), x.datatype())
39+
return x.create(flattenArray(x.toArray(), true), x.datatype())
3640
}
3741
})
3842
})

src/utils/array.js

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -465,40 +465,60 @@ function _unsqueeze (array, dims, dim) {
465465
* Flatten a multi dimensional array, put all elements in a one dimensional
466466
* array
467467
* @param {Array} array A multi dimensional array
468+
* @param {boolean} [isHomogeneous=false] Indicates if the size is homogeneous (like a valid matrix)
468469
* @return {Array} The flattened array (1 dimensional)
469470
*/
470-
export function flatten (array) {
471+
export function flatten (array, isHomogeneous = false) {
471472
if (!Array.isArray(array)) {
472473
// if not an array, return as is
473474
return array
474475
}
475-
if (typeof Array.prototype.flat === 'function') {
476-
return array.flat(Infinity)
476+
if (isHomogeneous) {
477+
return _flattenHomogeneous(array)
477478
} else {
478-
// TODO: once Array.prototype.flat is supported in all browsers, remove this and the _flatten function
479-
return _flatten(array)
479+
if (typeof Array.prototype.flat === 'function') {
480+
return array.flat(Infinity)
481+
} else {
482+
return _flattenFallback(array)
483+
}
480484
}
481485

482-
function _flatten (array) {
486+
function _flattenFallback (arr) {
487+
// remove this when Array.prototype.flat is broadly supported
483488
const flat = []
484-
485-
function flattenHelper (value) {
489+
_recurse(arr)
490+
return flat
491+
function _recurse (value) {
486492
if (Array.isArray(value)) {
487493
const len = value.length
488494
for (let i = 0; i < len; i++) {
489-
flattenHelper(value[i]) // traverse through sub-arrays recursively
495+
_recurse(value[i]) // traverse through sub-arrays recursively
490496
}
491497
} else {
492498
flat.push(value)
493499
}
494500
}
501+
}
495502

496-
const len = array.length
497-
for (let i = 0; i < len; i++) {
498-
flattenHelper(array[i])
499-
}
500-
503+
function _flattenHomogeneous (arr) {
504+
const flat = []
505+
_recurse(arr)
501506
return flat
507+
508+
function _recurse (value) {
509+
if (Array.isArray(value)) {
510+
const len = value.length
511+
if (Array.isArray(value[0])) {
512+
for (let i = 0; i < len; i++) {
513+
_recurse(value[i]) // traverse through sub-arrays recursively
514+
}
515+
} else {
516+
for (let i = 0; i < len; i++) {
517+
flat.push(value[i]) // traverse through sub-arrays without recursion
518+
}
519+
}
520+
}
521+
}
502522
}
503523
}
504524

0 commit comments

Comments
 (0)