Skip to content

Instantly share code, notes, and snippets.

@nescalante
Created August 16, 2013 14:13
Show Gist options
  • Save nescalante/6250286 to your computer and use it in GitHub Desktop.
Save nescalante/6250286 to your computer and use it in GitHub Desktop.
LINQ-style Javascript Array Extensions
Array.prototype.sum = function (selector) {
var source = this;
var totalSum = 0;
for (var i = 0; i < source.length; i++) {
totalSum += selector(source[i]);
}
return totalSum;
};
Array.prototype.select = function (selector) {
var source = this;
var array = [];
for (var i = 0; i < source.length; i++) {
array.push(selector(source[i]));
}
return array;
};
Array.prototype.selectMany = function (selector) {
var source = this;
var array = [];
for (var i = 0; i < source.length; i++) {
var innerArray = selector(source[i]);
if (innerArray.length) {
for (var j = 0; j < innerArray.length; j++) {
array.push(innerArray[j]);
}
}
}
return array;
};
Array.prototype.contains = function (item) {
var source = this;
for (var i = 0; i < source.length; i++) {
if (source[i] === item) {
return true;
}
}
return false;
};
Array.prototype.all = function (expression) {
var source = this;
var success = true;
for (var i = 0; i < source.length; i++) {
success = success && expression(source[i]);
}
return success;
};
Array.prototype.any = function (expression) {
if (expression === undefined) {
return this.length > 0;
}
var source = this;
for (var i = 0; i < source.length; i++) {
if (expression(source[i])) {
return true;
}
}
return false;
};
Array.prototype.where = function (expression) {
var source = this;
var array = [];
for (var i = 0; i < source.length; i++) {
if (expression(source[i])) {
array.push(source[i]);
}
}
return array;
};
Array.prototype.first = function (expression) {
var source = this,
result = source.where(expression);
return result.length > 0 ? result[0] : null;
};
Array.prototype.groupBy = function (selector) {
var source = this;
var array = [];
for (var i = 0; i < source.length; i++) {
var item = array.first(function (n) { return equalData(n.key, selector(source[i])); });
if (item === null) {
item = [];
item.key = selector(source[i]);
array.push(item);
}
item.push(source[i]);
}
return array;
function equalData(c, x) {
// date compare
if (c instanceof Date && x instanceof Date) {
return c.getTime() == x.getTime();
}
if (c instanceof Date != x instanceof Date) {
return false;
}
// type compare
if (typeof c !== typeof x) {
return false;
}
// number or string compare
if (typeof c === "number" || typeof c === "string") {
return c === x;
}
// object properties compare
for (var key in c) {
if (c[key] !== x[key]) {
return false;
}
}
// all seems to be right
return true;
}
};
Array.prototype.indexOf = Array.prototype.indexOf || function (elt /*, from*/) {
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0) ? Math.ceil(from) : Math.floor(from);
if (from < 0) {
from += len;
}
for (; from < len; from++) {
if (from in this && this[from] === elt) {
return from;
}
}
return -1;
};
Array.prototype.getType = function (selector) {
if (this.length == 0) return "undefined";
for (var i = 0; i < this.length; i++) {
var type = typeof selector(this[i]);
if (type == "number") return "number";
if (type == "string") return "string";
if (type == "boolean") return "boolean";
if (selector(this[i]) instanceof Date) return "Date";
}
return "undefined";
}
Array.prototype.orderBy = function (selector) {
if (this.length == 0) return;
var type = this.getType(selector);
if (type == "number") {
return this.sort(function (a, b) { return selector(a) - selector(b); });
}
else if (type == "string") {
return this.sort(function (a, b) {
var x = selector(a) || "",
y = selector(b) || "";
return x < y ? -1 : (x > y ? 1 : 0);
});
}
else if (type == "boolean") {
return this.sort(function (a, b) { return selector(a) == selector(b) ? 1 : -1 });
}
else if (type == "Date") {
return this.sort(function (a, b) { return (selector(a) || new Date(0)).getTime() - (selector(b) || new Date(0)).getTime(); });
}
else {
return this;
}
}
Array.prototype.orderByDescending = function (selector) {
if (this.length == 0) return;
var type = this.getType(selector);
if (type == "number") {
return this.sort(function (b, a) { return selector(a) - selector(b); });
}
else if (type == "string") {
return this.sort(function (b, a) {
var x = selector(a) || "",
y = selector(b) || "";
return x < y ? -1 : (x > y ? 1 : 0);
});
}
else if (type == "boolean") {
return this.sort(function (b, a) { return selector(a) == selector(b) ? -1 : 1 });;
}
else if (type == "Date") {
return this.sort(function (b, a) { return (selector(a) || new Date(0)).getTime() - (selector(b) || new Date(0)).getTime(); });
}
else {
return this;
}
}
@nescalante
Copy link
Author

Oh, and its deprecated. Use this happy library instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment