Skip to content

Instantly share code, notes, and snippets.

@SteveBate
Last active December 23, 2015 21:19
Show Gist options
  • Save SteveBate/6695654 to your computer and use it in GitHub Desktop.
Save SteveBate/6695654 to your computer and use it in GitHub Desktop.
A Javascript exercise to create a revealing module that exposes linq-style functional operators such as map, reduce, filter and others. Note that most of these operations are available on the Array class anyway.
var utils = utils || {};
utils.linq = function(){
range = function(start, end){
var numbers = [];
for(var x=start; x<=end;x++)
numbers.push(x);
return numbers;
}
where = function(values, predicate){
var filtered = [];
values.forEach(function(v){
if(predicate(v))
filtered.push(v);
});
return filtered;
}
select = function(values, mapper){
var mapped = [];
values.forEach(function(v){
mapped.push(mapper(v));
});
return mapped;
}
sum = function(values){
var result;
values.forEach(function(v){
if(result === undefined)
result = v;
else
result += v;
});
return result;
}
aggregate = function(values, fold, acc){
if(typeof acc === 'undefined')
throw "invalid accumulator";
var result = acc;
values.forEach(function(v){
result += fold(v);
});
return result;
}
zip = function(values1, values2){
var zipped = [];
values1.forEach(function(v){
zipped.push(v);
});
values2.forEach(function(v){
zipped.push(v);
});
return zipped;
}
return {
range : range,
filter : where,
map: select,
reduce: sum,
fold: aggregate,
zip: zip
}
};
var evens = l.filter(numbers, function(n){ return n % 2 === 0});
var odds = l.filter(numbers, function(n){ return n % 2 !== 0});
var xml = l.fold(l.filter(numbers, isEven), function(n){ return "<num>" + n + "</num>"}, "<numbers>") + "</numbers>";
var zipped = l.map(l.zip(evens, odds), function(n){ return n * 2});
var mapped = l.map(evens, function(n){ return n.toString() + '---'});
var sum = l.reduce(l.zip(evens, odds));
var isEven = function(v){
return v % 2 === 0;
};
var isOdd = function(v){
return v % 2 !== 0;
};
var toMultipliedString = function(v){
return (v * v).toString();
};
var toFloatString = function(v){
return v.toString() + ".00";
};
var surnameStartsWithLetter = function(customer){
return customer.surname.indexOf(getLetter()) === 0;
};
var getLetter = function(){
return "B";
};
var toCustomerProjection = function(c){
return { name : c.firstname + " " + c.surname };
};
var toXmlCustomer = function(c){
return "<customer>" + c.name + "</customer>";
};
var l = new utils.linq();
l.map(l.filter(l.range(1,10), isEven), toFloatString);
var customers = [
{ firstname: "Joe", surname: "Bloggs"},
{ firstname: "John", surname: "Smith"},
{ firstname: "Tom", surname:"Jones"},
{ firstname : "Steve", surname:"Bate"}
];
//l.map(l.filter(customers, surnameStartsWithLetter), toCustomer);
l.reduce(
l.map(
l.filter(customers, surnameStartsWithLetter),
toCustomerProjection),
toXmlCustomer, "<customers>") + "</customers>";
//var numbers = [1,2,3,4,5,6,7,8,9,10];
//l.reduce(l.filter(numbers, isEven), function(n){
// return n;
//},110);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment