1 | // underscore addon with sum, mean, median and nrange function |
---|
2 | // see details below |
---|
3 | |
---|
4 | _.mixin({ |
---|
5 | |
---|
6 | // Return sum of the elements |
---|
7 | sum : function(obj, iterator, context) { |
---|
8 | if (!iterator && _.isEmpty(obj)) return 0; |
---|
9 | var result = 0; |
---|
10 | if (!iterator && _.isArray(obj)){ |
---|
11 | for(var i=obj.length-1;i>-1;i-=1){ |
---|
12 | result += obj[i]; |
---|
13 | }; |
---|
14 | return result; |
---|
15 | }; |
---|
16 | each(obj, function(value, index, list) { |
---|
17 | var computed = iterator ? iterator.call(context, value, index, list) : value; |
---|
18 | result += computed; |
---|
19 | }); |
---|
20 | return result; |
---|
21 | }, |
---|
22 | |
---|
23 | // Return aritmethic mean of the elements |
---|
24 | // if an iterator function is given, it is applied before |
---|
25 | mean : function(obj, iterator, context) { |
---|
26 | if (!iterator && _.isEmpty(obj)) return Infinity; |
---|
27 | if (!iterator && _.isArray(obj)) return _.sum(obj)/obj.length; |
---|
28 | if (_.isArray(obj) && !_.isEmpty(obj)) return _.sum(obj, iterator, context)/obj.length; |
---|
29 | }, |
---|
30 | |
---|
31 | // Return median of the elements |
---|
32 | // if the object element number is odd the median is the |
---|
33 | // object in the "middle" of a sorted array |
---|
34 | // in case of an even number, the arithmetic mean of the two elements |
---|
35 | // in the middle (in case of characters or strings: obj[n/2-1] ) is returned. |
---|
36 | // if an iterator function is provided, it is applied before |
---|
37 | median : function(obj, iterator, context) { |
---|
38 | if (_.isEmpty(obj)) return Infinity; |
---|
39 | var tmpObj = []; |
---|
40 | if (!iterator && _.isArray(obj)){ |
---|
41 | tmpObj = _.clone(obj); |
---|
42 | tmpObj.sort(function(f,s){return f-s;}); |
---|
43 | }else{ |
---|
44 | _.isArray(obj) && each(obj, function(value, index, list) { |
---|
45 | tmpObj.push(iterator ? iterator.call(context, value, index, list) : value); |
---|
46 | tmpObj.sort(); |
---|
47 | }); |
---|
48 | }; |
---|
49 | return tmpObj.length%2 ? tmpObj[Math.floor(tmpObj.length/2)] : (_.isNumber(tmpObj[tmpObj.length/2-1]) && _.isNumber(tmpObj[tmpObj.length/2])) ? (tmpObj[tmpObj.length/2-1]+tmpObj[tmpObj.length/2]) /2 : tmpObj[tmpObj.length/2-1]; |
---|
50 | }, |
---|
51 | |
---|
52 | // Generate an integer Array containing an arithmetic progression. A port of |
---|
53 | // the native Python `range()` function. See |
---|
54 | // [the Python documentation](http://docs.python.org/library/functions.html#range). |
---|
55 | // replacement of old _.range() faster + incl. convenience operations: |
---|
56 | // _.nrange(start, stop) will automatically set step to +1/-1 |
---|
57 | // _.nrange(+/- stop) will automatically start = 0 and set step to +1/-1 |
---|
58 | nrange : function(start, stop, step) { |
---|
59 | if (arguments.length <= 1) { |
---|
60 | if (start === 0) |
---|
61 | return []; |
---|
62 | stop = start || 0; |
---|
63 | start = 0; |
---|
64 | } |
---|
65 | step = arguments[2] || 1*(start < stop) || -1; |
---|
66 | |
---|
67 | var len = Math.max(Math.ceil((stop - start) / step), 0); |
---|
68 | var idx = 0; |
---|
69 | var range = new Array(len); |
---|
70 | |
---|
71 | do { |
---|
72 | range[idx] = start; |
---|
73 | start += step; |
---|
74 | } while((idx += 1) < len); |
---|
75 | |
---|
76 | return range; |
---|
77 | } |
---|
78 | |
---|
79 | }) |
---|