Last active
December 18, 2015 03:39
-
-
Save jason-s13r/5719743 to your computer and use it in GitHub Desktop.
I've been nursing this in a JS Fiddle for a short time now. Just been playing with the LINQ methods and how they would be in JS. I find OrderBy and GroupBy are interesting.
This file contains hidden or 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 run = function (arr) { | |
'use strict'; | |
var onlyStrings = l('x => typeof x === "string"'); | |
var onlyNums = l('x => typeof x === "number"'); | |
var selector = l('x => typeof x'); | |
var grouper = l('x => typeof x'); | |
var selectE = l('x => x'); | |
var evenIndex = l('(x, index) => index % 2 === 0'); | |
console.clear(); | |
console.log(l.memory()); | |
console.log(arr.Select(), arr.Count()); | |
console.log(arr.First(), arr.Last()); | |
console.log('First', arr.First(onlyStrings)); | |
console.log('Last', arr.Last(onlyStrings)); | |
console.log('Select', arr.Select(selector)); | |
console.log('Count', arr.Count(onlyStrings)); | |
console.log('GroupBy', arr.GroupBy(grouper)); | |
console.log('Sum', arr.Sum(selectE)); | |
console.log('OrderBy', arr.OrderBy(selectE)); | |
console.log('OrderByDescending', arr.OrderByDescending(selectE)); | |
console.log('GroupBy (x, index) => index % 2 === 0', arr.GroupBy(evenIndex)); | |
console.log('GroupBy (x, index) => index % 2 === 0', arr.GroupBy('(x, index) => index % 2 === 0')); | |
}; | |
var l = (function () { | |
var memory = {}; | |
var lx = function (lambdaString) { | |
if (memory[lambdaString] !== undefined) { | |
return memory[lambdaString]; | |
} | |
var oneArg = /([a-zA-Z_][a-zA-Z0-9_]*)\ [\=\-]\>\ (.*)/; | |
var multiArgs = /\((([a-zA-Z_][a-zA-Z0-9_]*,?\ ?)+)\)\ [\=\-]\>\ (.*)/; | |
var parts = lambdaString.match(oneArg) || lambdaString.match(multiArgs); | |
var param = parts[1]; | |
var body = parts[parts.length - 1]; | |
body = body.split(/; ?/); | |
body = body.map(function (line, i) { | |
line = line.replace(/(^ +)|( +$)/, ''); | |
if (i === (body.length - 1) && !/return/.test(line)) { | |
line = 'return ' + line; | |
} | |
return ' ' + line; | |
}); | |
memory[lambdaString] = new Function(param, body.join(';\n') + ';'); | |
return memory[lambdaString]; | |
}; | |
lx.memory = function () { | |
return memory; | |
}; | |
return lx; | |
})(); | |
var first = function (arr, filter) { | |
filter = filter || (function (e) { | |
return true; | |
}); | |
var filtered = arr.filter(filter); | |
return filtered[0]; | |
}; | |
var last = function (arr, filter) { | |
filter = filter || (function (e) { | |
return true; | |
}); | |
var filtered = arr.filter(filter); | |
return filtered[filtered.length - 1]; | |
}; | |
var select = function (arr, selector) { | |
selector = selector || (function (e) { | |
return e; | |
}); | |
return arr.map(selector); | |
}; | |
var count = function (arr, filter) { | |
filter = filter || (function (e) { | |
return true; | |
}); | |
return arr.filter(filter).length; | |
}; | |
var groupBy = function (arr, grouper) { | |
grouper = grouper || (function (e) { | |
return e; | |
}); | |
var grouping = {}; | |
arr.forEach(function (e, i, a) { | |
var groups = this; | |
var group = grouper(e, i, a); | |
if (groups[group] === undefined) { | |
groups[group] = []; | |
} | |
groups[group].push(e); | |
}, grouping); | |
return Object.keys(grouping).map(function (e) { | |
return grouping[e]; | |
}); | |
}; | |
var sum = function (arr, selector, initial) { | |
initial = initial || 0; | |
selector = selector || (function (e) { | |
return e; | |
}); | |
return arr.reduce(function (p, c) { | |
return p + selector(c); | |
}, initial); | |
}; | |
var orderBy = function (arr, selector) { | |
selector = selector || (function (e) { | |
return e; | |
}); | |
var compare = function (a, b) { | |
var type = typeof selector(a); | |
if (type === 'number') { | |
return selector(a) - selector(b); | |
} else if (type === 'string') { | |
return selector(a).localeCompare(selector(b)); | |
} | |
}; | |
return [].slice.call(arr).sort(compare); | |
}; | |
var orderByDescending = function (arr, selector) { | |
return orderBy(arr, selector).reverse(); | |
}; | |
var take = function (arr, number) { | |
return arr.slice(0, number); | |
}; | |
var skip = function (arr, number) { | |
return arr.slice(number); | |
}; | |
var any = function (arr, condition) { | |
if (condition === null) { | |
return arr.length > 0; | |
} | |
return arr.some(condition); | |
}; | |
var where = function (arr, condition) { | |
condition = condition || (function (e) { | |
return true; | |
}); | |
return arr.filter(condition); | |
}; | |
Array.prototype.First = function (filter) { | |
if (typeof filter === 'string') { | |
filter = l(filter); | |
} | |
return first(this, filter); | |
}; | |
Array.prototype.Last = function (filter) { | |
if (typeof filter === 'string') { | |
filter = l(filter); | |
} | |
return last(this, filter); | |
}; | |
Array.prototype.Select = function (selector) { | |
if (typeof selector === 'string') { | |
selector = l(selector); | |
} | |
return select(this, selector); | |
}; | |
Array.prototype.Count = function (filter) { | |
if (typeof filter === 'string') { | |
filter = l(filter); | |
} | |
return count(this, filter); | |
}; | |
Array.prototype.GroupBy = function (grouper) { | |
if (typeof grouper === 'string') { | |
grouper = l(grouper); | |
} | |
return groupBy(this, grouper); | |
}; | |
Array.prototype.Sum = function (selector) { | |
if (typeof selector === 'string') { | |
selector = l(selector); | |
} | |
return sum(this, selector); | |
}; | |
Array.prototype.OrderBy = function (selector) { | |
if (typeof selector === 'string') { | |
selector = l(selector); | |
} | |
return orderBy(this, selector); | |
}; | |
Array.prototype.OrderByDescending = function (selector) { | |
if (typeof selector === 'string') { | |
selector = l(selector); | |
} | |
return orderByDescending(this, selector); | |
}; | |
Array.prototype.Take = function (number) { | |
if (typeof number === 'string') { | |
number = l(number); | |
} | |
return take(this, number); | |
}; | |
Array.prototype.Skip = function (number) { | |
if (typeof number === 'string') { | |
number = l(number); | |
} | |
return skip(this, number); | |
}; | |
Array.prototype.Any = function (condition) { | |
if (typeof condition === 'string') { | |
condition = l(condition); | |
} | |
return any(this, condition); | |
}; | |
Array.prototype.Where = function (condition) { | |
if (typeof condition === 'string') { | |
condition = l(condition); | |
} | |
return where(this, condition); | |
}; | |
run([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'one', 'two', 'three']); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment