1 | ;
|
2 |
|
3 | var object = require('./object');
|
4 | var 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 |
|
22 | exports.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 |
|
46 | exports.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 |
|
64 | exports.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 |
|
87 | exports.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 |
|
112 | exports.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 |
|
132 | exports.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 |
|
159 | exports.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 |
|
202 | exports.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 |
|
233 | exports.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 |
|
258 | exports.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 |
|
292 | exports.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 |
|
310 | exports.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 |
|
329 | exports.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 |
|
365 | exports.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 |
|
395 | exports.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 |
|
412 | exports.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 |