time-to-botec/squiggle/node_modules/@stdlib/utils/zip/lib/zip.js

182 lines
4.6 KiB
JavaScript
Raw Normal View History

/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
// MODULES //
var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive;
var isObject = require( '@stdlib/assert/is-plain-object' );
var isArray = require( '@stdlib/assert/is-array' );
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
// MAIN //
/**
* Generates array tuples from input arrays.
*
* @param {...Array} arr - input arrays to be zipped
* @param {Object} [opts] - function options
* @param {boolean} [opts.trunc=true] - boolean indicating whether to truncate arrays longer than the shortest input array
* @param {*} [opts.fill=null] - fill value used for arrays of unequal length
* @param {boolean} [opts.arrays=false] - boolean indicating whether an input array should be interpreted as an array of arrays to be zipped
* @throws {TypeError} must provide array arguments
* @throws {Error} must provide at least one array
* @throws {TypeError} options argument must be an object
* @throws {TypeError} must provide valid options
* @returns {Array} output array of arrays
*
* @example
* var zipped = zip( [ 1, 2 ], [ 'a', 'b' ] );
* // returns [ [ 1, 'a' ], [ 2, 'b' ] ]
*
* @example
* var zipped = zip( [ 1, 2, 3 ], [ 'a', 'b' ] );
* // returns [ [ 1, 'a' ], [ 2, 'b' ] ]
*
* @example
* var opts = {
* 'trunc': false
* };
*
* var zipped = zip( [ 1, 2, 3 ], [ 'a', 'b' ], opts );
* // returns [ [ 1, 'a' ], [ 2, 'b' ], [ 3, null ] ]
*
* @example
* var opts = {
* 'trunc': false,
* 'fill': ''
* };
*
* var zipped = zip( [ 1, 2, 3 ], [ 'a', 'b' ], opts );
* // returns [ [ 1, 'a' ], [ 2, 'b' ], [ 3, '' ] ]
*
* @example
* var arr = [ [ 1, 2 ], [ 'a', 'b' ] ];
*
* // Default behavior:
* var zipped = zip( arr );
* // returns [ [ [ 1, 2 ] ], [ [ 'a', 'b' ] ] ]
*
* // Array of arrays:
* zipped = zip( arr, { 'arrays': true } );
* // returns [ [ 1, 'a' ], [ 2, 'b' ] ]
*/
function zip() {
var nargs;
var args;
var fill;
var opts;
var arg;
var flg;
var len;
var arr;
var out;
var val;
var i;
var j;
opts = {};
fill = null;
args = Array.prototype.slice.call( arguments );
nargs = args.length;
for ( i = 0; i < nargs-1; i++ ) {
if ( !isArray( args[i] ) ) {
throw new TypeError( 'invalid argument. Must provide array arguments. Value: `' + args[i] + '`.' );
}
}
arg = args[ nargs-1 ];
flg = isObject( arg );
if ( !flg && !isArray( arg ) ) {
throw new TypeError( 'invalid argument. Last argument must be either an array or an options object. Value: `' + arg + '`.' );
}
if ( flg ) {
opts = args.pop();
}
nargs = args.length;
if ( nargs === 0 ) {
throw new Error( 'insufficient input arguments. Must provide at least one array.' );
}
if ( hasOwnProp( opts, 'trunc' ) ) {
if ( !isBoolean( opts.trunc ) ) {
throw new TypeError( 'invalid option. `trunc` option must be a boolean. Value: `' + opts.trunc + '`.' );
}
} else {
opts.trunc = true;
}
if ( hasOwnProp( opts, 'fill' ) ) {
fill = opts.fill;
}
if ( hasOwnProp( opts, 'arrays' ) ) {
if ( !isBoolean( opts.arrays ) ) {
throw new TypeError( 'invalid option. `arrays` option must be a boolean. Value: `' + opts.arrays + '`.' );
}
} else {
opts.arrays = false;
}
if ( nargs === 1 && opts.arrays ) {
// Treat the lone array argument as an array of arrays to be zipped...
args = args[ 0 ];
nargs = args.length;
}
len = args[ 0 ].length;
if ( opts.trunc ) {
// Find the min array length...
for ( i = 0; i < nargs; i++ ) {
val = args[ i ].length;
if ( val < len ) {
len = val;
}
}
} else {
// Find the max array length...
for ( i = 0; i < nargs; i++ ) {
val = args[ i ].length;
if ( val > len ) {
len = val;
}
}
}
out = new Array( len );
for ( j = 0; j < len; j++ ) {
// Temporary array to store tuples...
arr = new Array( nargs );
// Create the tuples...
for ( i = 0; i < nargs; i++ ) {
arg = args[ i ];
// If an array is too short, use a fill value...
if ( arg.length <= j ) {
arr[ i ] = fill;
continue;
}
arr[ i ] = arg[ j ];
}
out[ j ] = arr;
}
return out;
}
// EXPORTS //
module.exports = zip;