Last active
December 23, 2015 21:19
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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