UNPKG

8.35 kBJavaScriptView Raw
1'use strict';
2
3var object = require('./object');
4var utils = require('./utils');
5
6/**
7 * Returns true if `value` is an array.
8 *
9 * ```js
10 * <%= isArray('a, b, c') %>
11 * //=> 'false'
12 *
13 * <%= isArray(['a, b, c']) %>
14 * //=> 'true'
15 * ```
16 *
17 * @param {*} `value` The value to test.
18 * @return {Boolean}
19 * @api public
20 */
21
22exports.isArray = function isArray(val) {
23 return Array.isArray(val);
24};
25
26/**
27 * Cast `val` to an array.
28 *
29 * ```js
30 * <%= arrayify('a') %>
31 * //=> '["a"]'
32 *
33 * <%= arrayify({a: 'b'}) %>
34 * //=> '[{a: "b"}]'
35 *
36 * <%= arrayify(['a']) %>
37 * //=> '["a"]'
38 * ```
39 *
40 * @param {*} `val` The value to arrayify.
41 * @return {Array} An array.
42 * @return {Array}
43 * @api public
44 */
45
46exports.arrayify = function arrayify(val) {
47 return val ? (Array.isArray(val) ? val : [val]) : [];
48};
49
50/**
51 * Returns the first item, or first `n` items of an array.
52 *
53 * ```js
54 * <%= first(['a', 'b', 'c', 'd', 'e'], 2) %>
55 * //=> '["a", "b"]'
56 * ```
57 *
58 * @param {Array} `array`
59 * @param {Number} `n` Number of items to return, starting at `0`.
60 * @return {Array}
61 * @api public
62 */
63
64exports.first = function first(arr, n) {
65 if (utils.isEmpty(arr)) return '';
66 if (utils.isNumber(n)) {
67 return arr.slice(0, n);
68 } else {
69 return arr[0];
70 }
71};
72
73/**
74 * Returns the last item, or last `n` items of an array.
75 *
76 * ```js
77 * <%= last(['a', 'b', 'c', 'd', 'e'], 2) %>
78 * //=> '["d", "e"]'
79 * ```
80 *
81 * @param {Array} `array`
82 * @param {Number} `n` Number of items to return, starting with the last item.
83 * @return {Array}
84 * @api public
85 */
86
87exports.last = function last(arr, n) {
88 if (utils.isEmpty(arr)) return '';
89 if (!utils.isNumber(n)) {
90 return arr[arr.length - 1];
91 } else {
92 return arr.slice(-n);
93 }
94};
95
96/**
97 * Returns all of the items in an array up to the specified number
98 * Opposite of `<%= after() %`.
99 *
100 * ```js
101 * <%= before(['a', 'b', 'c'], 2) %>
102 * //=> '["a", "b"]'
103 * ```
104 *
105 * @param {Array} `array`
106 * @param {Number} `n`
107 * @return {Array} Array excluding items after the given number.
108 * @crosslink after
109 * @api public
110 */
111
112exports.before = function before(arr, n) {
113 return !utils.isEmpty(arr) ? arr.slice(0, -n) : '';
114};
115
116/**
117 * Returns all of the items in an arry after the specified index.
118 * Opposite of `<%= before() %`.
119 *
120 * ```js
121 * <%= after(['a', 'b', 'c'], 1) %>
122 * //=> '["c"]'
123 * ```
124 *
125 * @param {Array} `array` Collection
126 * @param {Number} `n` Starting index (number of items to exclude)
127 * @return {Array} Array exluding `n` items.
128 * @crosslink before
129 * @api public
130 */
131
132exports.after = function after(arr, n) {
133 return !utils.isEmpty(arr) ? arr.slice(n) : '';
134};
135
136/**
137 * Calling `fn` on each element of the given `array` with
138 * the given `context`.
139 *
140 * ```js
141 * function double(str) {
142 * return str + str;
143 * }
144 * ```
145 *
146 * Assuming that `double` has been registered as a helper:
147 *
148 * ```js
149 * <%= each(['a', 'b', 'c'], double, ctx) %>
150 * //=> '["aa", "bb", "cc"]'
151 * ```
152 *
153 * @param {Array} `array`
154 * @param {String} `fn` The function to call on each element in the given array.
155 * @return {String}
156 * @api public
157 */
158
159exports.each = function each(arr, fn, context) {
160 if (utils.isEmpty(arr)) {
161 return '';
162 }
163
164 var ctx = object.merge({}, this && this.context, context);
165 var len = arr.length;
166 var idx = -1;
167 var res = '';
168 var val;
169
170 while (++idx < len) {
171 if ((val = fn.call(context, arr[idx], idx, arr)) === false) {
172 break;
173 }
174 res += val;
175 }
176 return res;
177};
178
179/**
180 * Returns a new array, created by calling `function`
181 * on each element of the given `array`.
182 *
183 * ```js
184 * function double(str) {
185 * return str + str;
186 * }
187 * ```
188 *
189 * Assuming that `double` has been registered as a helper:
190 *
191 * ```js
192 * <%= map(['a', 'b', 'c'], double) %>
193 * //=> '["aa", "bb", "cc"]'
194 * ```
195 *
196 * @param {Array} `array`
197 * @param {String} `fn` The function to call on each element in the given array.
198 * @return {String}
199 * @api public
200 */
201
202exports.map = function map(arr, fn, context) {
203 if (utils.isEmpty(arr)) return '';
204
205 var len = arr.length;
206 var res = new Array(len);
207 var idx = -1;
208
209 while (++idx < len) {
210 res[idx] = fn.call(context, arr[idx], idx, arr);
211 }
212 return res;
213};
214
215/**
216 * Join all elements of array into a string, optionally using a
217 * given separator.
218 *
219 * ```js
220 * <%= join(['a', 'b', 'c']) %>
221 * //=> 'a, b, c'
222 *
223 * <%= join(['a', 'b', 'c'], '-') %>
224 * //=> 'a-b-c'
225 * ```
226 *
227 * @param {Array} `array`
228 * @param {String} `sep` The separator to use.
229 * @return {String}
230 * @api public
231 */
232
233exports.join = function join(arr, sep) {
234 if (utils.isEmpty(arr)) return '';
235 sep = typeof sep !== 'string' ? ', ' : sep;
236 return arr.join(sep);
237};
238
239/**
240 * Sort the given `array`. If an array of objects is passed,
241 * you may optionally pass a `key` to sort on as the second
242 * argument. You may alternatively pass a sorting function as
243 * the second argument.
244 *
245 * ```js
246 * <%= sort(["b", "a", "c"]) %>
247 * //=> 'a,b,c'
248 *
249 * <%= sort([{a: "zzz"}, {a: "aaa"}], "a") %>
250 * //=> '[{"a":"aaa"},{"a":"zzz"}]'
251 * ```
252 *
253 * @param {Array} `array` the array to sort.
254 * @param {String|Function} `key` The object key to sort by, or sorting function.
255 * @api public
256 */
257
258exports.sort = function sort(arr, key) {
259 if (utils.isEmpty(arr)) return '';
260 if (typeof key === 'function') {
261 return arr.sort(key);
262 }
263
264 if (typeof key !== 'string') {
265 return arr.sort();
266 }
267
268 return arr.sort(function(a, b) {
269 if (object.isObject(a) && typeof a[key] === 'string') {
270 return a[key].localeCompare(b[key]);
271 } else if (typeof a === 'string') {
272 return a.localeCompare(b);
273 } else {
274 return a > b;
275 }
276 });
277};
278
279/**
280 * Returns the length of the given array.
281 *
282 * ```js
283 * <%= length(['a', 'b', 'c']) %>
284 * //=> 3
285 * ```
286 *
287 * @param {Array} `array`
288 * @return {Number} The length of the array.
289 * @api public
290 */
291
292exports.length = function length(arr) {
293 if (utils.isEmpty(arr)) return '';
294 return Array.isArray(arr) ? arr.length : 0;
295};
296
297/**
298 * Returns an array with all falsey values removed.
299 *
300 * ```js
301 * <%= compact([null, a, undefined, 0, false, b, c, '']) %>
302 * //=> '["a", "b", "c"]'
303 * ```
304 *
305 * @param {Array} `arr`
306 * @return {Array}
307 * @api public
308 */
309
310exports.compact = function compact(arr) {
311 return !utils.isEmpty(arr) ? arr.filter(Boolean) : '';
312};
313
314/**
315 * Return the difference between the first array and
316 * additional arrays.
317 *
318 * ```js
319 * <%= difference(["a", "c"], ["a", "b"]) %>
320 * //=> '["c"]'
321 * ```
322 *
323 * @param {Array} `array` The array to compare againts.
324 * @param {Array} `arrays` One or more additional arrays.
325 * @return {Array}
326 * @api public
327 */
328
329exports.difference = function difference(a, b, c) {
330 if (utils.isEmpty(a)) return '';
331 var len = a.length;
332 var arr = [];
333 var rest;
334
335 if (!b) {
336 return a;
337 }
338
339 if (!c) {
340 rest = b;
341 } else {
342 rest = [].concat.apply([], [].slice.call(arguments, 1));
343 }
344 while (len--) {
345 if (rest.indexOf(a[len]) === -1) {
346 arr.unshift(a[len]);
347 }
348 }
349 return arr;
350};
351
352/**
353 * Return an array, free of duplicate values.
354 *
355 * ```js
356 * <%= unique(['a', 'b', 'c', 'c']) %
357 * => '["a", "b", "c"]'
358 * ```
359 *
360 * @param {Array} `array` The array to uniquify
361 * @return {Array} Duplicate-free array
362 * @api public
363 */
364
365exports.unique = function unique(arr) {
366 if (utils.isEmpty(arr)) return '';
367 var len = arr.length;
368 var i = -1;
369
370 while (i++ < len) {
371 var j = i + 1;
372
373 for (; j < arr.length; ++j) {
374 if (arr[i] === arr[j]) {
375 arr.splice(j--, 1);
376 }
377 }
378 }
379 return arr;
380};
381
382/**
383 * Returns an array of unique values using strict equality for comparisons.
384 *
385 * ```js
386 * <%= union(["a"], ["b"], ["c"]) %>
387 * //=> '["a", "b", "c"]'
388 * ```
389 *
390 * @param {Array} `arr`
391 * @return {Array}
392 * @api public
393 */
394
395exports.union = function union(arr) {
396 return !utils.isEmpty(arr) ? utils.union([], [].concat.apply([], arguments)) : '';
397};
398
399/**
400 * Shuffle the items in an array.
401 *
402 * ```js
403 * <%= shuffle(["a", "b", "c"]) %>
404 * //=> ["c", "a", "b"]
405 * ```
406 *
407 * @param {Array} `arr`
408 * @return {Array}
409 * @api public
410 */
411
412exports.shuffle = function shuffle(arr) {
413 var len = arr.length;
414 var res = new Array(len);
415 var i = -1;
416
417 while (++i < len) {
418 var rand = utils.random(0, i);
419 if (i != rand) {
420 res[i] = res[rand];
421 }
422 res[rand] = arr[i];
423 }
424 return res;
425};
426
\No newline at end of file