forked from OperationSpark/lodown
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
389 lines (329 loc) · 11.9 KB
/
Copy pathindex.js
File metadata and controls
389 lines (329 loc) · 11.9 KB
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
'use strict';
/**
* START OF OUR LIBRARY!
*/
/**
identity: Returns the same value that is used as the argument. In math: f(x) = x
This function looks useless, but is used throughout Underscore as a default iteratee.
Returns <value> unchanged
@Param {Any value}
*/
function identity(value) {
return value;
}
module.exports.identity = identity;
/**
typeOf:returns a string indicating the type of the unevaluated operand.
Returns the type of value as a string
@Param {Any value}
*/
function typeOf (value){
if (value === null){
return 'null';
}else if (Array.isArray(value)){
return 'array';
}else{
return typeof value;
}
}
module.exports.typeOf = typeOf;
/**
first: Returns the first element of an array. Passing n will return the first n elements of the array.
If array is not an array, returns []. If {number} is not given or not a number, returns just the first element in {array}.
Otherwise, returns the first <number> items of {array}
@Param An array
@Param A number
*/
function first(array, number){
var arr = [];
if (!Array.isArray(array)){
return [];
}
if (typeof number !== 'number'){
return array[0];
}else if (number > array.length){
return array;
}else if (number < 0){
return [];
}else {
for (var i = 0; i < number; i++){
arr.push(array[i]);
}
return arr;
}
}
module.exports.first = first;
/**
last: Returns the last element of an array. Passing n will return the last n elements of the array.
If {array} is not an array, returns [], if {number} is not given or not a number, returns just the last element in {array}.
Otherwise, returns the last {number} items of <array>
@Param {An array}
@Param {A number}
*/
function last(array, number){
if (!Array.isArray(array)){
return [];
}
if (typeof number !== 'number'){
return array[array.length - 1];
}else if (number > array.length){
return array;
}else if (number < 0){
return [];
}else {
return array.slice(array.length - number);
}
}
module.exports.last = last;
/**
indexOf: Returns the index at which value can be found in the array, or -1 if value is not present in the array.
Returns the index of <array> that is the first occurrance of <value>
Returns -1 if <value> is not in <array>
@Param An array
@Param A value
*/
function indexOf(array, value){
for (var i = 0; i < array.length; i++){
if (array[i] === value){
return i;
}
}
return -1;
}
module.exports.indexOf = indexOf;
/**
contains:Returns true if the value is present in the list. Uses indexOf internally, if list is an Array. Use fromIndex to start your search at a given index.
Returns true if {array} contains {value}, and returns false otherwise
@Param An array
@Param A value
*/
function contains(array, value){
for (var i = 0; i < array.length; i++){
if (array[i] === value){
return true;
}
}
return false;
}
module.exports.contains = contains;
/**
each: Designed to loop over a collection, Array or Object, and applies the
action Function to each value in the collection.
@param {Array or Object} collection: The collection over which to iterate.
@param {Function} action: The Function to be applied to each value in the
collection
*/
function each(collection, fn){
var arr1 = [];
if (Array.isArray(collection)){
for (var i = 0; i < collection.length; i++){
fn(collection[i], i, collection);
}
}else if (typeof collection === 'object' && collection !== null){
for (let key in collection) {
fn(collection[key], key, collection);
}
}
}
module.exports.each = each;
/**
unique: Produces a duplicate-free version of the array, using === to test object equality.
In particular only the first occurrence of each value is kept.
Returns a new array of all elements from {array} with duplicates removed
@Param {An array}
*/
function unique(array){
var arr = [];
var arr2 = [];
for (var i = 0; i < array.length; i++){
arr.push(indexOf(array, array[i]));
}
for (var j = 0; j < arr.length; j++){
if (arr[j] === j){
arr2.push(array[j]);
}
}
return arr2;
}
module.exports.unique = unique;
/**
filter: Looks through each value in the list, returning an array of all the values that pass a truth test (predicate).
Returns a new array of elements for which calling <function> returned true
@Param {An array}: The collection whose elements are tested.
@Param {A function}: calls {function} for each element in {array} passing the arguments: the {element}, {index}, {array}
*/
function filter(array, fn){
var arr = [];
each(array, function(e,i,a){
if (fn(e,i,a)) arr.push(e);
});
return arr;
}
module.exports.filter = filter;
/**
reject: Returns the values in list without the elements that the truth test (predicate) passes. The opposite of filter.
Returns a new array of elements for which calling {function} returned false
@Param {An array}: The collection whose elements are tested.
@Param {A function}: calls {function} for each element in {array} passing the arguments: the {element}, {index}, {array}
*/
function reject(array, fn){
var arr = array.slice();
var arr2 = [];
var rej = filter(array, fn);
for (var i = 0; i < rej.length; i++){
for (var j = 0; j < array.length; j++ ){
if (rej[i] === array[j]){
delete arr[j];
}
}
}
for (var k = 0; k < arr.length; k++){
if(arr[k] !== undefined){
arr2.push(arr[k]);
}
}
return arr2;
}
module.exports.reject = reject;
/**
partition: Split list into two arrays: one whose elements all satisfy predicate and one whose elements all do not satisfy predicate.
Returns an array that is made up of 2 sub arrays:
1)An array that contains all the values for which <function> returned something truthy
2)An array that contains all the values for which <function> returned something falsy
@Param {An array}: The collection whose elements are tested.
@Param {A function}: calls {function} for each element in {array} passing the arguments: the {element}, {index}, {array}
*/
function partition(array, fn){
return [filter(array,fn),reject(array,fn)];
}
module.exports.partition = partition;
/**\
map: Produces a new array of values by mapping each value in list through a transformation function (iteratee). The iteratee is passed three arguments: the value, then the index (or key) of the iteration, and finally a reference to the entire list.
Returns the value of each <function> call in a new array
@Param {A collection}: An array or object
@Param {a function}: calls {function} for each element in {collection} passing the arguments: if {collection} === arr: the element, it's index, {collection}
if {collection} is an object: current value, current key, <collection>
*/
function map(collection, fn){
var arr = [];
var arr2 = [];
each(collection, function(e,i,a){
arr.push(fn(e,i,a));
});
return arr;
}
module.exports.map = map;
/**
pluck: A convenient version of what is perhaps the most common use-case for map: extracting a list of property values.
Returns an array containing the value of {property} for every element in <array>
@Param {An array of objects}: array which has objects inside
@Param {A property}: key name which we are looking for values of
*/
function pluck(array, property){
return map(array,x => x[property]);
}
module.exports.pluck = pluck;
/**
every: Returns true if all of the values in the list pass the predicate truth test.
Short-circuits and stops traversing the list if a false element is found.
If the return value of calling {function} for every element is true, returns true
If even one of them returns false, returns false
If {function} is not provided, returns true if every element is truthy, otherwise return false
@Param {A collection}: The collection whose elements are tested.
@Param {A function}:Calls {function} for every element of <collection> with the paramaters: if {collection} === array: element, index, {collection}
if {collection} is an object: current value, current key, <collection>
*/
function every(collection, fn){
if (typeof fn === 'function'){
var map1 = map(collection,fn);
for (var i = 0; i < map1.length; i++){
if (map1[i] === false){
return false;
}
}
return true;
}else{
for (var j = 0; j < collection.length; j++){
if (collection[j] === true){
return true;
}else if(collection[j] === false){
return false;
}
}
}
}
module.exports.every = every;
/**
some: Returns true if any of the values in the list pass the predicate truth test. Short-circuits and stops traversing the list if a true element is found.
If the return value of calling {function} is true for at least one element, returns true
If it is false for all elements, returns false
If {function} is not provided return true if at least one element is truthy, otherwise returns false
@Param: {A collection}: The collection whose elements are tested.
@Param: {A function}:Calls {function} for every element of <collection> with the paramaters: if {collection} === array: element, index, {collection}
if {collection} is an object: current value, current key, <collection>
*/
function some(collection, fn){
if (typeof fn === 'function'){
var map1 = map(collection,fn)
for (var i = 0; i < map1.length; i++){
if (map1[i] === true){
return true
}
}
return false
}else{
for (var j = 0; j < collection.length; j++){
if (collection[j] === true){
return true;
}else if(collection[j] === false){
return false;
}
}
}
}
module.exports.some = some;
/**
reduce: Also known as inject and fold, reduce boils down a list of values into a single value.
After the last iteration, returns the return value of the final {function} call
@Param: {An array}: The array whose elements are reduced
@Param: {A function}: Calls {function} for every element in {collection} passing the arguments: previous result, element, index.
Use the returns value of {function} as the "previous result" for the next iteration
@Param: {A seed}: On the very first iteration, uses {seed} as the "previous result"
If no {seed} was given, uses the first element/value of {collection} as {seed} and continue to the next element
*/
function reduce(array, fn, seed){
var sum;
if (seed === undefined || seed === 'null'){
sum = array[0];
for(var j = 1; j < array.length; j++){
sum = fn(sum, array[j], j);
}
}else{
for (var i = 0; i < array.length; i++){
if (i === 0){
sum = fn(seed, array[i], i);
}else{
sum = fn(sum, array[i], i);
}
}
}
return sum;
}
module.exports.reduce = reduce;
/**
extend: Shallowly copy all of the properties in the source objects over to the destination object, and return the destination object.
Any nested objects or arrays will be copied by reference, not duplicated.
It's in-order, so the last source will override properties of the same name in previous arguments.
Returns the update {object 1}
@Param {An Object}: Copy properties to the first Obj from the later Objects.
@Param {Any number of objects}: If more objects are passed in, copy their properties to {object 1} as well, in the order they are passed in.
*/
function extend(obj1){
for (var i = 0;i < arguments.length; i++){
for (var key in arguments[i+1]){
obj1[key] = arguments[i+1][key];
}
}
return obj1;
}
module.exports.extend = extend;