time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

zip.js (4678B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 'use strict';
     20 
     21 // MODULES //
     22 
     23 var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive;
     24 var isObject = require( '@stdlib/assert/is-plain-object' );
     25 var isArray = require( '@stdlib/assert/is-array' );
     26 var hasOwnProp = require( '@stdlib/assert/has-own-property' );
     27 
     28 
     29 // MAIN //
     30 
     31 /**
     32 * Generates array tuples from input arrays.
     33 *
     34 * @param {...Array} arr - input arrays to be zipped
     35 * @param {Object} [opts] - function options
     36 * @param {boolean} [opts.trunc=true] - boolean indicating whether to truncate arrays longer than the shortest input array
     37 * @param {*} [opts.fill=null] - fill value used for arrays of unequal length
     38 * @param {boolean} [opts.arrays=false] - boolean indicating whether an input array should be interpreted as an array of arrays to be zipped
     39 * @throws {TypeError} must provide array arguments
     40 * @throws {Error} must provide at least one array
     41 * @throws {TypeError} options argument must be an object
     42 * @throws {TypeError} must provide valid options
     43 * @returns {Array} output array of arrays
     44 *
     45 * @example
     46 * var zipped = zip( [ 1, 2 ], [ 'a', 'b' ] );
     47 * // returns [ [ 1, 'a' ], [ 2, 'b' ] ]
     48 *
     49 * @example
     50 * var zipped = zip( [ 1, 2, 3 ], [ 'a', 'b' ] );
     51 * // returns [ [ 1, 'a' ], [ 2, 'b' ] ]
     52 *
     53 * @example
     54 * var opts = {
     55 *     'trunc': false
     56 * };
     57 *
     58 * var zipped = zip( [ 1, 2, 3 ], [ 'a', 'b' ], opts );
     59 * // returns [ [ 1, 'a' ], [ 2, 'b' ], [ 3, null ] ]
     60 *
     61 * @example
     62 * var opts = {
     63 *     'trunc': false,
     64 *     'fill': ''
     65 * };
     66 *
     67 * var zipped = zip( [ 1, 2, 3 ], [ 'a', 'b' ], opts );
     68 * // returns [ [ 1, 'a' ], [ 2, 'b' ], [ 3, '' ] ]
     69 *
     70 * @example
     71 * var arr = [ [ 1, 2 ], [ 'a', 'b' ] ];
     72 *
     73 * // Default behavior:
     74 * var zipped = zip( arr );
     75 * // returns [ [ [ 1, 2 ] ], [ [ 'a', 'b' ] ] ]
     76 *
     77 * // Array of arrays:
     78 * zipped = zip( arr, { 'arrays': true } );
     79 * // returns [ [ 1, 'a' ], [ 2, 'b' ] ]
     80 */
     81 function zip() {
     82 	var nargs;
     83 	var args;
     84 	var fill;
     85 	var opts;
     86 	var arg;
     87 	var flg;
     88 	var len;
     89 	var arr;
     90 	var out;
     91 	var val;
     92 	var i;
     93 	var j;
     94 
     95 	opts = {};
     96 	fill = null;
     97 	args = Array.prototype.slice.call( arguments );
     98 	nargs = args.length;
     99 
    100 	for ( i = 0; i < nargs-1; i++ ) {
    101 		if ( !isArray( args[i] ) ) {
    102 			throw new TypeError( 'invalid argument. Must provide array arguments. Value: `' + args[i] + '`.' );
    103 		}
    104 	}
    105 	arg = args[ nargs-1 ];
    106 	flg = isObject( arg );
    107 	if ( !flg && !isArray( arg ) ) {
    108 		throw new TypeError( 'invalid argument. Last argument must be either an array or an options object. Value: `' + arg + '`.' );
    109 	}
    110 	if ( flg ) {
    111 		opts = args.pop();
    112 	}
    113 	nargs = args.length;
    114 	if ( nargs === 0 ) {
    115 		throw new Error( 'insufficient input arguments. Must provide at least one array.' );
    116 	}
    117 	if ( hasOwnProp( opts, 'trunc' ) ) {
    118 		if ( !isBoolean( opts.trunc ) ) {
    119 			throw new TypeError( 'invalid option. `trunc` option must be a boolean.  Value: `' + opts.trunc + '`.' );
    120 		}
    121 	} else {
    122 		opts.trunc = true;
    123 	}
    124 	if ( hasOwnProp( opts, 'fill' ) ) {
    125 		fill = opts.fill;
    126 	}
    127 	if ( hasOwnProp( opts, 'arrays' ) ) {
    128 		if ( !isBoolean( opts.arrays ) ) {
    129 			throw new TypeError( 'invalid option. `arrays` option must be a boolean. Value: `' + opts.arrays + '`.' );
    130 		}
    131 	} else {
    132 		opts.arrays = false;
    133 	}
    134 	if ( nargs === 1 && opts.arrays ) {
    135 		// Treat the lone array argument as an array of arrays to be zipped...
    136 		args = args[ 0 ];
    137 		nargs = args.length;
    138 	}
    139 	len = args[ 0 ].length;
    140 	if ( opts.trunc ) {
    141 		// Find the min array length...
    142 		for ( i = 0; i < nargs; i++ ) {
    143 			val = args[ i ].length;
    144 			if ( val < len ) {
    145 				len = val;
    146 			}
    147 		}
    148 	} else {
    149 		// Find the max array length...
    150 		for ( i = 0; i < nargs; i++ ) {
    151 			val = args[ i ].length;
    152 			if ( val > len ) {
    153 				len = val;
    154 			}
    155 		}
    156 	}
    157 	out = new Array( len );
    158 	for ( j = 0; j < len; j++ ) {
    159 		// Temporary array to store tuples...
    160 		arr = new Array( nargs );
    161 
    162 		// Create the tuples...
    163 		for ( i = 0; i < nargs; i++ ) {
    164 			arg = args[ i ];
    165 
    166 			// If an array is too short, use a fill value...
    167 			if ( arg.length <= j ) {
    168 				arr[ i ] = fill;
    169 				continue;
    170 			}
    171 			arr[ i ] = arg[ j ];
    172 		}
    173 		out[ j ] = arr;
    174 	}
    175 	return out;
    176 }
    177 
    178 
    179 // EXPORTS //
    180 
    181 module.exports = zip;