Skip to content

Instantly share code, notes, and snippets.

@jgphilpott
Last active September 20, 2023 13:33
Show Gist options
  • Save jgphilpott/a1367ca419ac2807ed4340d69356b7f1 to your computer and use it in GitHub Desktop.
Save jgphilpott/a1367ca419ac2807ed4340d69356b7f1 to your computer and use it in GitHub Desktop.
A collection of JavaScript Array prototype updates.
# Info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
# Info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
# Source: https://gist.github.com/jgphilpott/a1367ca419ac2807ed4340d69356b7f1
Object.defineProperty Array.prototype, "first",
value: ->
this.at 0
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "last",
value: ->
this.at -1
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "clear",
value: ->
this.length = 0
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "empty",
value: ->
this.length is 0
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "boolean",
value: ->
Boolean this.length
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "number",
value: ->
Number this
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "string",
value: ->
String this
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "array",
value: ->
Array this
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "object",
value: ->
Object this
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "sum",
value: ->
numeric = this.numeric()
if not numeric.empty()
return numeric.reduce((a, b) -> a + b)
else
return 0
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "difference",
value: ->
numeric = this.numeric()
if not numeric.empty()
return numeric.reduce((a, b) -> a - b)
else
return 0
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "product",
value: ->
numeric = this.numeric()
if not numeric.empty()
return numeric.reduce((a, b) -> a * b)
else
return 0
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "quotient",
value: ->
numeric = this.numeric()
if not numeric.empty()
return numeric.reduce((a, b) -> a / b)
else
return 0
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "min",
value: (numeric = true) ->
if numeric
return Math.min.apply null, this.numeric()
else
return this.sort().first()
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "max",
value: (numeric = true) ->
if numeric
return Math.max.apply null, this.numeric()
else
return this.sort().last()
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "absMin",
value: (numeric = true) ->
if numeric
return Math.min.apply null, this.numeric().map Math.abs
else
return this.sort().first()
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "absMax",
value: (numeric = true) ->
if numeric
return Math.max.apply null, this.numeric().map Math.abs
else
return this.sort().last()
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "mean",
value: ->
numeric = this.numeric()
if not numeric.empty()
return numeric.sum() / numeric.length
else
return null
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "median",
value: ->
numeric = this.numeric().sort()
if not numeric.empty()
low = numeric[ Math.floor (numeric.length - 1) / 2 ]
high = numeric[ Math.ceil (numeric.length - 1) / 2 ]
return (low + high) / 2
else
return null
configurable: false,
enumerable: false,
writable: false
Object.defineProperty Array.prototype, "mode",
value: (counts = false) ->
numeric = this.numeric()
if not numeric.empty()
tally = {}
for element in numeric
if tally[element] is undefined then tally[element] = 0
tally[element] += 1
if counts then return tally
max = Object.values(tally).max()
return Object.keys(tally).filter((element) => tally[element] is max).map Number
else
return null
configurable: false,
enumerable: false,
writable: false
# Credit: https://stackoverflow.com/a/10757602/1544937
# Credit: https://stackoverflow.com/a/20070691/1544937
Object.defineProperty Array.prototype, "unique",
value: ->
Array.from new Set this
configurable: false,
enumerable: false,
writable: false
# Credit: https://stackoverflow.com/a/53606357/1544937
Object.defineProperty Array.prototype, "subset",
value: (array = []) ->
this.every (item) -> array.includes item
configurable: false,
enumerable: false,
writable: false
# Credit: https://stackoverflow.com/a/24137301/1544937
Object.defineProperty Array.prototype, "random",
value: ->
this[ Math.floor(Math.random() * this.length) ]
configurable: false,
enumerable: false,
writable: false
# Credit: https://stackoverflow.com/a/70669834/1544937
Object.defineProperty Array.prototype, "numeric",
value: (cast = true) ->
numeric = this.filter (item) -> /^-?\d+\.?\d*$/.test item
return if cast then numeric.map Number else numeric
configurable: false,
enumerable: false,
writable: false
# Credit: https://stackoverflow.com/a/57067151/1544937
Object.defineProperty Array.prototype, "exclude",
value: (condition, item) ->
count = 0
for element, index in this
if not condition.call item, element, index, this
if index isnt count
this[count] = element
count++
this.length = count
return this
configurable: false,
enumerable: false,
writable: false
// Info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
// Info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
// Source: https://gist.github.com/jgphilpott/a1367ca419ac2807ed4340d69356b7f1
Object.defineProperty(Array.prototype, "first", {
value: function() {
return this.at(0);
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "last", {
value: function() {
return this.at(-1);
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "clear", {
value: function() {
return this.length = 0;
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "empty", {
value: function() {
return this.length === 0;
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "boolean", {
value: function() {
return Boolean(this.length);
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "number", {
value: function() {
return Number(this);
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "string", {
value: function() {
return String(this);
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "array", {
value: function() {
return Array(this);
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "object", {
value: function() {
return Object(this);
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "sum", {
value: function() {
var numeric;
numeric = this.numeric();
if (!numeric.empty()) {
return numeric.reduce(function(a, b) {
return a + b;
});
} else {
return 0;
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "difference", {
value: function() {
var numeric;
numeric = this.numeric();
if (!numeric.empty()) {
return numeric.reduce(function(a, b) {
return a - b;
});
} else {
return 0;
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "product", {
value: function() {
var numeric;
numeric = this.numeric();
if (!numeric.empty()) {
return numeric.reduce(function(a, b) {
return a * b;
});
} else {
return 0;
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "quotient", {
value: function() {
var numeric;
numeric = this.numeric();
if (!numeric.empty()) {
return numeric.reduce(function(a, b) {
return a / b;
});
} else {
return 0;
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "min", {
value: function(numeric = true) {
if (numeric) {
return Math.min.apply(null, this.numeric());
} else {
return this.sort().first();
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "max", {
value: function(numeric = true) {
if (numeric) {
return Math.max.apply(null, this.numeric());
} else {
return this.sort().last();
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "absMin", {
value: function(numeric = true) {
if (numeric) {
return Math.min.apply(null, this.numeric().map(Math.abs));
} else {
return this.sort().first();
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "absMax", {
value: function(numeric = true) {
if (numeric) {
return Math.max.apply(null, this.numeric().map(Math.abs));
} else {
return this.sort().last();
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "mean", {
value: function() {
var numeric;
numeric = this.numeric();
if (!numeric.empty()) {
return numeric.sum() / numeric.length;
} else {
return null;
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "median", {
value: function() {
var high, low, numeric;
numeric = this.numeric().sort();
if (!numeric.empty()) {
low = numeric[Math.floor((numeric.length - 1) / 2)];
high = numeric[Math.ceil((numeric.length - 1) / 2)];
return (low + high) / 2;
} else {
return null;
}
},
configurable: false,
enumerable: false,
writable: false
});
Object.defineProperty(Array.prototype, "mode", {
value: function(counts = false) {
var element, i, len, max, numeric, tally;
numeric = this.numeric();
if (!numeric.empty()) {
tally = {};
for (i = 0, len = numeric.length; i < len; i++) {
element = numeric[i];
if (tally[element] === void 0) {
tally[element] = 0;
}
tally[element] += 1;
}
if (counts) {
return tally;
}
max = Object.values(tally).max();
return Object.keys(tally).filter((element) => {
return tally[element] === max;
}).map(Number);
} else {
return null;
}
},
configurable: false,
enumerable: false,
writable: false
});
// Credit: https://stackoverflow.com/a/10757602/1544937
// Credit: https://stackoverflow.com/a/20070691/1544937
Object.defineProperty(Array.prototype, "unique", {
value: function() {
return Array.from(new Set(this));
},
configurable: false,
enumerable: false,
writable: false
});
// Credit: https://stackoverflow.com/a/53606357/1544937
Object.defineProperty(Array.prototype, "subset", {
value: function(array = []) {
return this.every(function(item) {
return array.includes(item);
});
},
configurable: false,
enumerable: false,
writable: false
});
// Credit: https://stackoverflow.com/a/24137301/1544937
Object.defineProperty(Array.prototype, "random", {
value: function() {
return this[Math.floor(Math.random() * this.length)];
},
configurable: false,
enumerable: false,
writable: false
});
// Credit: https://stackoverflow.com/a/70669834/1544937
Object.defineProperty(Array.prototype, "numeric", {
value: function(cast = true) {
var numeric;
numeric = this.filter(function(item) {
return /^-?\d+\.?\d*$/.test(item);
});
if (cast) {
return numeric.map(Number);
} else {
return numeric;
}
},
configurable: false,
enumerable: false,
writable: false
});
// Credit: https://stackoverflow.com/a/57067151/1544937
Object.defineProperty(Array.prototype, "exclude", {
value: function(condition, item) {
var count, element, i, index, len, ref;
count = 0;
ref = this;
for (index = i = 0, len = ref.length; i < len; index = ++i) {
element = ref[index];
if (!condition.call(item, element, index, this)) {
if (index !== count) {
this[count] = element;
}
count++;
}
}
this.length = count;
return this;
},
configurable: false,
enumerable: false,
writable: false
});
@jgphilpott
Copy link
Author

Prototyping

This gist is part of a collection of gists that extend JavaScript data prototypes such as Boolean, Number, String, Array and Object. See below for links to all the gists:

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