'use strict'; // MODULES // var isPositiveInteger = require( 'validate.io-positive-integer' ), isArray = require( 'validate.io-array' ), ndarrayLike = require( 'validate.io-ndarray-like' ), createCopy = require( 'utils-copy' ); // DIMS // /** * FUNCTION: dims( x, d, max ) * Computes array dimensions. * * @private * @param {Array} arr - input array * @param {Array} d - dimensions array * @param {Number} max - max number of dimensions * @returns {Array} dimensions array */ function dims( arr, d, max ) { if ( max && d.length === max ) { return; } if ( !isArray( arr[0] ) ) { return; } d.push( arr[0].length ); dims( arr[ 0 ], d, max ); } // end FUNCTION dims() /** * FUNCTION: check( arr, d ) * Checks that all array elements have the same dimensions. * * @private * @param {Array} arr - input array * @param {Array} d - dimensions array * @returns {Boolean} boolean indicating if all array elements have the same dimensions */ function check( arr, d ) { var len = arr.length, dim = d.shift(), nDims = d.length, val, flg; for ( var i = 0; i < len; i++ ) { val = arr[ i ]; if ( !isArray( val ) || val.length !== dim ) { return false; } if ( nDims ) { flg = check( val, d.slice() ); if ( !flg ) { return false; } } } return true; } // end FUNCTION check() /** * FUNCTION: compute( x[, max] ) * Computes dimensions. * * @param {Array} x - input object * @param {Number} [max] - limits the number of dimensions returned * @returns {Array|null} array of dimensions or null */ function compute( x, max ) { var d, flg; if ( arguments.length > 1 ) { if ( !isPositiveInteger( max ) ) { throw new TypeError( 'dims()::invalid input argument. `max` option must be a positive integer.' ); } } if ( ndarrayLike( x ) === true ) { d = createCopy( x.shape ); if ( max && max <= d.length ) { d.length = max; } return d; } if ( isArray( x ) ) { // [0] Initialize the dimensions array: d = [ x.length ]; // [1] Recursively determine array dimensions: dims( x, d, max ); // [2] Check that all array element dimensions are consistent... if ( d.length > 1 ) { flg = check( x, d.slice( 1 ) ); if ( !flg ) { return null; } } return d; } throw new TypeError( 'dims()::invalid input argument. Must provide an array, matrix or ndarray.' ); } // end FUNCTION compute() // EXPORTS // module.exports = compute;