UNPKG

join-array

Version:

Join the elements of an array into a string. Indicate the regular and the last one separator. Indicate the maximum number of items to concatenate.

84 lines (76 loc) 3.58 kB
/* global Function, Infinity */ const argumentsTypes = require('typeof-arguments'); const propertiesTypes = require('typeof-properties'); const type = require('of-type'); const moduleName = require('./package.json').name; module.exports = function (config){ /* The first argument must be of type [Object] or [Array] */ argumentsTypes(arguments,[[Array,Object]],(o)=>{ throw new TypeError(`${moduleName}: ${o.message}`); }); /* Check if the first argument is [Object] */ const hasObjectConfig = type(config,Object); /*The properties of the [Object] config can be omitted. Then the default valued are attached. */ const defaults = { separator:', ', last:' and ', max:Infinity, maxMessage:(missed)=>`(${missed} more...)`, each:null }; if(!hasObjectConfig){ /* The first argument is not [Object], so all arguments are validated. */ argumentsTypes(arguments,[Array,[String,null,undefined],[String,null,undefined],[Number,null,undefined],[Function,String,null,undefined],[Function,null,undefined]],(o)=>{ /* If any of the passed arguments does not match the expected type, throw an error. */ throw new TypeError(`${moduleName}: ${o.message}`); }); /* Arguments are valid and are converted into [Object] config object. * It is to unify the passed arguments, regardless they are given as [Object] config object or as separate arguments. * Then the further code always take [Object] config object for the computations. */ const argumentsToObject = {}; const properties = ['array','separator','last','max','maxMessage','each']; for(var i in arguments){ argumentsToObject[properties[i]] = arguments[i]; } config = argumentsToObject; } else { /* The first argument is [Object] so the properties of this [Object] argument are validated. * The 'expected' object contains the expected types of the given properties. * If the first argument is [Object], the next arguments are ignored. */ const expected = { array:Array, separator:[String,null,undefined], last:[String,null,undefined], max:[Number,null,undefined], maxMessage:[Function,String,null,undefined], each:[Function,null,undefined] }; propertiesTypes(config,expected,(o)=>{ /* If any of the properties does not match the expected type, throw an error. */ throw new TypeError(`${moduleName}: Invalid [Object] config argument. ${o.message}`); }); } /* The not defined properties or arguments are replaced with default values. */ for(var i in defaults){ if(type(config[i],[null,undefined])) config[i] = defaults[i]; } /* The arguments are valid. * The [Object] config object is ready to be computed. */ var message = ""; var eachDefined = type(config.each,Function); for(var i=0;i<config.array.length;i++){ if(i===config.max-1 && config.array.length>config.max){ /* Check the type of maxMessage, if [Function], call it and pass the missed items number. */ const maxMessage = type(config.maxMessage,String) ? config.maxMessage:config.maxMessage(config.array.length-1-i); message += maxMessage + config.last; i = config.array.length-2; continue; } var item = config.array[i]; if(eachDefined) item = config.each(item,i,config.array); message += item; if(i<config.array.length-2) message += config.separator; if(i===config.array.length-2) message += config.last; } return message; };