Skip to content

Instantly share code, notes, and snippets.

@nwwells
Created November 13, 2015 21:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nwwells/facc6dcaf16068a660ba to your computer and use it in GitHub Desktop.
Save nwwells/facc6dcaf16068a660ba to your computer and use it in GitHub Desktop.
var ko = require('knockout');
require('FunctionalArrays')(ko);
var obsArr = ko.observableArray();
var only3CharsArr = obsArr.filter(function (element) { return element.length === 3; });
// obsArr() === []
// only3CharsArr() === []
obsArr.push('hello');
// obsArr() === ['hello']
// only3CharsArr() === []
obsArr.push('yes');
// obsArr() === ['hello', 'yes']
// only3CharsArr() === ['yes']
define(function (require) {
'use strict';
var _ = require('underscore');
//functionName -> isCopy
var ARRAY_FUNCTIONS = {
'every': false,
'filter': false,
'forEach': false,
'join': false,
'lastIndexOf': false,
'map': false,
'reduce': false,
'reduceRight': false,
'reverse': true,
'some': false,
'sort': true
};
var makeComputed = function (ko, thisArg, fn) {
var computed = ko.pureComputed(fn, thisArg);
addFunctionalMethods(computed, ko, true);
return computed;
};
var find = function (array, predicate, context) {
var result;
array.some(function(value, index, list) {
if (predicate.call(context, value, index, list)) {
result = value;
return true;
}
});
return result;
};
var matches = function (predicates) {
return function (obj) {
for (var key in predicates) {
if (predicates[key]() !== obj[key]()) return false;
}
return true;
};
};
function addFunctionalMethods(proto, ko, noCopy) {
_.each(ARRAY_FUNCTIONS, function(isCopy, functionName) {
var currentFunction = Array.prototype[functionName];
var reallyCopy = isCopy && !noCopy;
proto[reallyCopy ? functionName + 'Copy' : functionName] = function () {
var args = arguments;
return makeComputed(ko, this, function () {
var array = this();
if (reallyCopy) array = array.slice();
return currentFunction.apply(array, args);
});
};
});
proto.find = function (predicate, context) {
return makeComputed(ko, this, function () {
return find(this(), predicate, context);
});
};
proto.where = function (predicates) {
return makeComputed(ko, this, function () {
return this().filter(matches(predicates));
});
};
proto.findWhere = function (predicates) {
return makeComputed(ko, this, function () {
return find(this(), matches(predicates));
});
};
proto.countBy = function (key, seed) {
return makeComputed(ko, this, function () {
return this().reduce(function (counts, dm) {
var value = dm[key]();
if (!(value in counts)) counts[value] = 1;
else counts[value]++;
return counts;
}, seed || {});
});
};
proto.first = function () {
return this.find(ƒ.T);
};
}
return function(ko) {
addFunctionalMethods(ko.observableArray.fn, ko);
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment