UNPKG

8.29 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 len = arr.length;
165 var idx = -1;
166 var res = '';
167 var val;
168
169 while (++idx < len) {
170 if ((val = fn.call(context, arr[idx], idx, arr)) === false) {
171 break;
172 }
173 res += val;
174 }
175 return res;
176};
177
178/**
179 * Returns a new array, created by calling `function`
180 * on each element of the given `array`.
181 *
182 * ```js
183 * function double(str) {
184 * return str + str;
185 * }
186 * ```
187 *
188 * Assuming that `double` has been registered as a helper:
189 *
190 * ```js
191 * <%= map(['a', 'b', 'c'], double) %>
192 * //=> '["aa", "bb", "cc"]'
193 * ```
194 *
195 * @param {Array} `array`
196 * @param {String} `fn` The function to call on each element in the given array.
197 * @return {String}
198 * @api public
199 */
200
201exports.map = function map(arr, fn, context) {
202 if (utils.isEmpty(arr)) return '';
203
204 var len = arr.length;
205 var res = new Array(len);
206 var idx = -1;
207
208 while (++idx < len) {
209 res[idx] = fn.call(context, arr[idx], idx, arr);
210 }
211 return res;
212};
213
214/**
215 * Join all elements of array into a string, optionally using a
216 * given separator.
217 *
218 * ```js
219 * <%= join(['a', 'b', 'c']) %>
220 * //=> 'a, b, c'
221 *
222 * <%= join(['a', 'b', 'c'], '-') %>
223 * //=> 'a-b-c'
224 * ```
225 *
226 * @param {Array} `array`
227 * @param {String} `sep` The separator to use.
228 * @return {String}
229 * @api public
230 */
231
232exports.join = function join(arr, sep) {
233 if (utils.isEmpty(arr)) return '';
234 sep = typeof sep !== 'string' ? ', ' : sep;
235 return arr.join(sep);
236};
237
238/**
239 * Sort the given `array`. If an array of objects is passed,
240 * you may optionally pass a `key` to sort on as the second
241 * argument. You may alternatively pass a sorting function as
242 * the second argument.
243 *
244 * ```js
245 * <%= sort(["b", "a", "c"]) %>
246 * //=> 'a,b,c'
247 *
248 * <%= sort([{a: "zzz"}, {a: "aaa"}], "a") %>
249 * //=> '[{"a":"aaa"},{"a":"zzz"}]'
250 * ```
251 *
252 * @param {Array} `array` the array to sort.
253 * @param {String|Function} `key` The object key to sort by, or sorting function.
254 * @api public
255 */
256
257exports.sort = function sort(arr, key) {
258 if (utils.isEmpty(arr)) return '';
259 if (typeof key === 'function') {
260 return arr.sort(key);
261 }
262
263 if (typeof key !== 'string') {
264 return arr.sort();
265 }
266
267 return arr.sort(function(a, b) {
268 if (object.isObject(a) && typeof a[key] === 'string') {
269 return a[key].localeCompare(b[key]);
270 } else if (typeof a === 'string') {
271 return a.localeCompare(b);
272 } else {
273 return a > b;
274 }
275 });
276};
277
278/**
279 * Returns the length of the given array.
280 *
281 * ```js
282 * <%= length(['a', 'b', 'c']) %>
283 * //=> 3
284 * ```
285 *
286 * @param {Array} `array`
287 * @return {Number} The length of the array.
288 * @api public
289 */
290
291exports.length = function length(arr) {
292 if (utils.isEmpty(arr)) return '';
293 return Array.isArray(arr) ? arr.length : 0;
294};
295
296/**
297 * Returns an array with all falsey values removed.
298 *
299 * ```js
300 * <%= compact([null, a, undefined, 0, false, b, c, '']) %>
301 * //=> '["a", "b", "c"]'
302 * ```
303 *
304 * @param {Array} `arr`
305 * @return {Array}
306 * @api public
307 */
308
309exports.compact = function compact(arr) {
310 return !utils.isEmpty(arr) ? arr.filter(Boolean) : '';
311};
312
313/**
314 * Return the difference between the first array and
315 * additional arrays.
316 *
317 * ```js
318 * <%= difference(["a", "c"], ["a", "b"]) %>
319 * //=> '["c"]'
320 * ```
321 *
322 * @param {Array} `array` The array to compare againts.
323 * @param {Array} `arrays` One or more additional arrays.
324 * @return {Array}
325 * @api public
326 */
327
328exports.difference = function difference(a, b, c) {
329 if (utils.isEmpty(a)) return '';
330 var len = a.length;
331 var arr = [];
332 var rest;
333
334 if (!b) {
335 return a;
336 }
337
338 if (!c) {
339 rest = b;
340 } else {
341 rest = [].concat.apply([], [].slice.call(arguments, 1));
342 }
343 while (len--) {
344 if (rest.indexOf(a[len]) === -1) {
345 arr.unshift(a[len]);
346 }
347 }
348 return arr;
349};
350
351/**
352 * Return an array, free of duplicate values.
353 *
354 * ```js
355 * <%= unique(['a', 'b', 'c', 'c']) %
356 * => '["a", "b", "c"]'
357 * ```
358 *
359 * @param {Array} `array` The array to uniquify
360 * @return {Array} Duplicate-free array
361 * @api public
362 */
363
364exports.unique = function unique(arr) {
365 if (utils.isEmpty(arr)) return '';
366 var len = arr.length;
367 var i = -1;
368
369 while (i++ < len) {
370 var j = i + 1;
371
372 for (; j < arr.length; ++j) {
373 if (arr[i] === arr[j]) {
374 arr.splice(j--, 1);
375 }
376 }
377 }
378 return arr;
379};
380
381/**
382 * Returns an array of unique values using strict equality for comparisons.
383 *
384 * ```js
385 * <%= union(["a"], ["b"], ["c"]) %>
386 * //=> '["a", "b", "c"]'
387 * ```
388 *
389 * @param {Array} `arr`
390 * @return {Array}
391 * @api public
392 */
393
394exports.union = function union(arr) {
395 return !utils.isEmpty(arr) ? utils.union([], [].concat.apply([], arguments)) : '';
396};
397
398/**
399 * Shuffle the items in an array.
400 *
401 * ```js
402 * <%= shuffle(["a", "b", "c"]) %>
403 * //=> ["c", "a", "b"]
404 * ```
405 *
406 * @param {Array} `arr`
407 * @return {Array}
408 * @api public
409 */
410
411exports.shuffle = function shuffle(arr) {
412 var len = arr.length;
413 var res = new Array(len);
414 var i = -1;
415
416 while (++i < len) {
417 var rand = utils.random(0, i);
418 if (i !== rand) {
419 res[i] = res[rand];
420 }
421 res[rand] = arr[i];
422 }
423 return res;
424};
425
\No newline at end of file