-
Notifications
You must be signed in to change notification settings - Fork 117
/
underscore.function.predicates.js
107 lines (87 loc) · 3.76 KB
/
underscore.function.predicates.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Underscore-contrib (underscore.function.predicates.js 0.3.0)
// (c) 2013 Michael Fogus, DocumentCloud and Investigative Reporters & Editors
// Underscore-contrib may be freely distributed under the MIT license.
// Establish the root object, `window` in the browser, or `require` it on the server.
if (typeof exports === 'object') {
_ = module.exports = require('underscore');
}
// Helpers
// -------
// Mixing in the predicate functions
// ---------------------------------
_.mixin({
// A wrapper around instanceof
isInstanceOf: function(x, t) { return (x instanceof t); },
// An associative object is one where its elements are
// accessed via a key or index. (i.e. array and object)
isAssociative: function(x) { return _.isArray(x) || _.isObject(x) || _.isArguments(x); },
// An indexed object is anything that allows numerical index for
// accessing its elements (e.g. arrays and strings). NOTE: Underscore
// does not support cross-browser consistent use of strings as array-like
// objects, so be wary in IE 8 when using String objects and IE<8.
// on string literals & objects.
isIndexed: function(x) { return _.isArray(x) || _.isString(x) || _.isArguments(x); },
// A seq is something considered a sequential composite type (i.e. arrays and `arguments`).
isSequential: function(x) { return (_.isArray(x)) || (_.isArguments(x)); },
// Check if an object is an object literal, since _.isObject(function() {}) === _.isObject([]) === true
isPlainObject: function(x) { return _.isObject(x) && x.constructor === Object; },
// These do what you think that they do
isZero: function(x) { return 0 === x; },
isEven: function(x) { return _.isFinite(x) && (x & 1) === 0; },
isOdd: function(x) { return _.isFinite(x) && !_.isEven(x); },
isPositive: function(x) { return x > 0; },
isNegative: function(x) { return x < 0; },
isValidDate: function(x) { return _.isDate(x) && !_.isNaN(x.getTime()); },
// A numeric is a variable that contains a numeric value, regardless its type
// It can be a String containing a numeric value, exponential notation, or a Number object
// See here for more discussion: http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric/1830844#1830844
isNumeric: function(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
},
// An integer contains an optional minus sign to begin and only the digits 0-9
// Objects that can be parsed that way are also considered ints, e.g. "123"
// Floats that are mathematically equal to integers are considered integers, e.g. 1.0
// See here for more discussion: http://stackoverflow.com/questions/1019515/javascript-test-for-an-integer
isInteger: function(i) {
return _.isNumeric(i) && i % 1 === 0;
},
// A float is a numbr that is not an integer.
isFloat: function(n) {
return _.isNumeric(n) && !_.isInteger(n);
},
// checks if a string is a valid JSON
isJSON: function(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
},
// Returns true if its arguments are monotonically
// increaing values; false otherwise.
isIncreasing: function() {
var count = _.size(arguments);
if (count === 1) return true;
if (count === 2) return arguments[0] < arguments[1];
for (var i = 1; i < count; i++) {
if (arguments[i-1] >= arguments[i]) {
return false;
}
}
return true;
},
// Returns true if its arguments are monotonically
// decreaing values; false otherwise.
isDecreasing: function() {
var count = _.size(arguments);
if (count === 1) return true;
if (count === 2) return arguments[0] > arguments[1];
for (var i = 1; i < count; i++) {
if (arguments[i-1] <= arguments[i]) {
return false;
}
}
return true;
}
});