-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathampersand-collection-lodash-mixin.js
84 lines (71 loc) · 2.42 KB
/
ampersand-collection-lodash-mixin.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
/*$AMPERSAND_VERSION*/
var _ = require('lodash');
var slice = [].slice;
var mixins = {};
// lodash methods that we want to implement on the Collection.
var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find',
'filter', 'reject', 'every', 'some', 'includes', 'invoke', 'max', 'min',
'take', 'initial', 'tail', 'drop', 'without', 'difference', 'indexOf', 'shuffle',
'lastIndexOf', 'isEmpty', 'sample', 'partition'
];
// Mix in each lodash method as a proxy to `Collection#models`.
_.each(methods, function (method) {
if (!_[method]) return;
mixins[method] = function () {
var len = arguments.length;
var args = Array(len + 1);
args[0] = this.models;
for (var i = 0; i < len; i++) {
args[i + 1] = arguments[i];
}
return _[method].apply(_, args);
};
});
// lodash methods that take a property name as an argument.
var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'keyBy'];
// Use attributes instead of properties.
_.each(attributeMethods, function (method) {
if (!_[method]) return;
mixins[method] = function (value, context) {
var iterator = _.isFunction(value) ? value : function (model) {
return model.get ? model.get(value) : model[value];
};
return _[method](this.models, iterator, context);
};
});
// Return models with matching attributes. Useful for simple cases of
// `filter`.
mixins.where = function (attrs, first) {
if (_.isEmpty(attrs)) return first ? void 0 : [];
return this[first ? 'find' : 'filter'](function (model) {
var value;
for (var key in attrs) {
value = model.get ? model.get(key) : model[key];
if (attrs[key] !== value) return false;
}
return true;
});
};
// Return the first model with matching attributes. Useful for simple cases
// of `find`.
mixins.findWhere = function (attrs) {
return this.where(attrs, true);
};
// Plucks an attribute from each model in the collection.
mixins.pluck = function (attr) {
return _.invokeMap(this.models, 'get', attr);
};
// We implement the following trivial methods ourselves.
// Gets first model
mixins.first = function () {
return this.models[0];
};
// Gets last model
mixins.last = function () {
return this.models[this.models.length - 1];
};
// Gets size of collection
mixins.size = function () {
return this.models.length;
};
module.exports = mixins;