1 |
|
2 | "use strict";
|
3 |
|
4 | var isArray = Array.isArray;
|
5 | function isObject(o) {
|
6 |
|
7 | return new Object(o) === o;
|
8 |
|
9 | }
|
10 |
|
11 |
|
12 | function isNaN(n) {
|
13 | return typeof n === "number" && n !== n;
|
14 | }
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 | function sort(arr) {
|
27 | var res = arr.slice();
|
28 | res.sort();
|
29 | return res;
|
30 | }
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | function isEqual(a, b) {
|
38 | var i;
|
39 |
|
40 | if (isNaN(a) && isNaN(b)) {
|
41 | return true;
|
42 | }
|
43 |
|
44 | if (a === b) {
|
45 | return true;
|
46 | } else if (isArray(a) && isArray(b) && a.length === b.length) {
|
47 | for (i = 0; i < a.length; i++) {
|
48 | if (!isEqual(a[i], b[i])) {
|
49 | return false;
|
50 | }
|
51 | }
|
52 | return true;
|
53 | } else if (isObject(a) && isObject(b) && !isArray(a) && !isArray(b)) {
|
54 | var akeys = Object.keys(a);
|
55 | var bkeys = Object.keys(b);
|
56 | if (!isEqual(sort(akeys), sort(bkeys))) {
|
57 | return false;
|
58 | }
|
59 |
|
60 | for (i = 0; i < akeys.length; i++) {
|
61 | if (!isEqual(a[akeys[i]], b[akeys[i]])) {
|
62 | return false;
|
63 | }
|
64 | }
|
65 | return true;
|
66 | }
|
67 |
|
68 | return false;
|
69 | }
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 | function isApproxEqual(x, y, opts) {
|
85 | opts = opts || {};
|
86 | var fnEqual = opts.fnEqual !== false;
|
87 | var depth = opts.depth || 5;
|
88 |
|
89 |
|
90 | var state = [];
|
91 |
|
92 | function loop(a, b, n) {
|
93 | if (isNaN(a) && isNaN(b)) {
|
94 | return true;
|
95 | }
|
96 |
|
97 |
|
98 | if (a === b) {
|
99 | return true;
|
100 | }
|
101 |
|
102 |
|
103 | if (n >= depth) {
|
104 | return true;
|
105 | }
|
106 |
|
107 | var i;
|
108 |
|
109 |
|
110 | for (i = 0; i < state.length; i++) {
|
111 | if (state[i][0] === a && state[i][1] === b) {
|
112 | return true;
|
113 | }
|
114 | }
|
115 |
|
116 |
|
117 | state.push([a, b]);
|
118 |
|
119 | if (typeof a === "function" && typeof b === "function") {
|
120 | return fnEqual;
|
121 | }
|
122 |
|
123 | if (isArray(a) && isArray(b) && a.length === b.length) {
|
124 | for (i = 0; i < a.length; i++) {
|
125 | if (!loop(a[i], b[i], n + 1)) {
|
126 | return false;
|
127 | }
|
128 | }
|
129 | return true;
|
130 | } else if (isObject(a) && isObject(b) && !isArray(a) && !isArray(b)) {
|
131 | var akeys = Object.keys(a);
|
132 | var bkeys = Object.keys(b);
|
133 | if (!loop(sort(akeys), sort(bkeys), n + 1)) {
|
134 | return false;
|
135 | }
|
136 |
|
137 | for (i = 0; i < akeys.length; i++) {
|
138 | if (!loop(a[akeys[i]], b[akeys[i]], n + 1)) {
|
139 | return false;
|
140 | }
|
141 | }
|
142 | return true;
|
143 | }
|
144 |
|
145 | return false;
|
146 | }
|
147 | return loop(x, y, 0);
|
148 | }
|
149 |
|
150 | function identity(x) {
|
151 | return x;
|
152 | }
|
153 |
|
154 | function pluck(arr, key) {
|
155 | return arr.map(function (e) {
|
156 | return e[key];
|
157 | });
|
158 | }
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 | function force(arb) {
|
166 | return (typeof arb === "function") ? arb() : arb;
|
167 | }
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 | function merge() {
|
175 | var res = {};
|
176 |
|
177 | for (var i = 0; i < arguments.length; i++) {
|
178 | var arg = arguments[i];
|
179 | var keys = Object.keys(arg);
|
180 | for (var j = 0; j < keys.length; j++) {
|
181 | var key = keys[j];
|
182 | res[key] = arg[key];
|
183 | }
|
184 | }
|
185 |
|
186 | return res;
|
187 | }
|
188 |
|
189 | function div2(x) {
|
190 | return Math.floor(x / 2);
|
191 | }
|
192 |
|
193 | function log2(x) {
|
194 | return Math.log(x) / Math.log(2);
|
195 | }
|
196 |
|
197 | function ilog2(x) {
|
198 | return x <= 0 ? 0 : Math.floor(log2(x));
|
199 | }
|
200 |
|
201 | function curriedN(n) {
|
202 | var n1 = n - 1;
|
203 | return function curriedNInstance(result, args) {
|
204 | if (args.length === n) {
|
205 | return result(args[n1]);
|
206 | } else {
|
207 | return result;
|
208 | }
|
209 | };
|
210 | }
|
211 |
|
212 | var curried2 = curriedN(2);
|
213 | var curried3 = curriedN(3);
|
214 |
|
215 | function charArrayToString(arr) {
|
216 | return arr.join("");
|
217 | }
|
218 |
|
219 | function stringToCharArray(str) {
|
220 | return str.split("");
|
221 | }
|
222 |
|
223 | function pairArrayToDict(arrayOfPairs) {
|
224 | var res = {};
|
225 | arrayOfPairs.forEach(function (p) {
|
226 | res[p[0]] = p[1];
|
227 | });
|
228 | return res;
|
229 | }
|
230 |
|
231 | function dictToPairArray(m) {
|
232 | var res = [];
|
233 | Object.keys(m).forEach(function (k) {
|
234 | res.push([k, m[k]]);
|
235 | });
|
236 | return res;
|
237 | }
|
238 |
|
239 | function partition(arr, pred) {
|
240 | var truthy = [];
|
241 | var falsy = [];
|
242 |
|
243 | for (var i = 0; i < arr.length; i++) {
|
244 | var x = arr[i];
|
245 | if (pred(x)) {
|
246 | truthy.push(x);
|
247 | } else {
|
248 | falsy.push(x);
|
249 | }
|
250 | }
|
251 |
|
252 | return [truthy, falsy];
|
253 | }
|
254 |
|
255 | module.exports = {
|
256 | isArray: isArray,
|
257 | isObject: isObject,
|
258 | isEqual: isEqual,
|
259 | isApproxEqual: isApproxEqual,
|
260 | identity: identity,
|
261 | pluck: pluck,
|
262 | force: force,
|
263 | merge: merge,
|
264 | div2: div2,
|
265 | ilog2: ilog2,
|
266 | curried2: curried2,
|
267 | curried3: curried3,
|
268 | charArrayToString: charArrayToString,
|
269 | stringToCharArray: stringToCharArray,
|
270 | pairArrayToDict: pairArrayToDict,
|
271 | dictToPairArray: dictToPairArray,
|
272 | partition: partition,
|
273 | };
|