112 lines
3.2 KiB
JavaScript
112 lines
3.2 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.isIterable = isIterable;
|
|
exports.ifArray = ifArray;
|
|
exports.toArray = toArray;
|
|
exports.compact = compact;
|
|
exports.filterInPlace = filterInPlace;
|
|
exports.uniq = uniq;
|
|
exports.shallowArrayEql = shallowArrayEql;
|
|
exports.sortBy = sortBy;
|
|
exports.leastBy = leastBy;
|
|
const Object_1 = require("./Object");
|
|
const String_1 = require("./String");
|
|
function isIterable(obj) {
|
|
return ((0, Object_1.isObject)(obj) && Symbol.iterator in obj) || Array.isArray(obj);
|
|
}
|
|
function ifArray(arr) {
|
|
return Array.isArray(arr) ? arr : undefined;
|
|
}
|
|
function toArray(arr) {
|
|
return Array.isArray(arr) // < strings are not arrays
|
|
? arr
|
|
: arr == null
|
|
? []
|
|
: (0, String_1.isString)(arr) // < don't rely on isIterable rejecting Strings
|
|
? [arr]
|
|
: isIterable(arr)
|
|
? Array.from(arr)
|
|
: [arr];
|
|
}
|
|
function compact(array) {
|
|
return array.filter((elem) => elem != null);
|
|
}
|
|
/**
|
|
* Remove all elements from the given array that return false from the given
|
|
* predicate `filter`.
|
|
*/
|
|
function filterInPlace(arr, filter) {
|
|
let j = 0;
|
|
arr.forEach((ea, i) => {
|
|
if (filter(ea)) {
|
|
if (i !== j)
|
|
arr[j] = ea;
|
|
j++;
|
|
}
|
|
});
|
|
arr.length = j;
|
|
return arr;
|
|
}
|
|
function uniq(arr) {
|
|
return arr.reduce((acc, ea) => {
|
|
if (acc.indexOf(ea) === -1)
|
|
acc.push(ea);
|
|
return acc;
|
|
}, []);
|
|
}
|
|
// terrible implementation only for internal use
|
|
function shallowArrayEql(a, b) {
|
|
return (a != null &&
|
|
b != null &&
|
|
a.length === b.length &&
|
|
a.every((ea, idx) => ea === b[idx]));
|
|
}
|
|
/**
|
|
* Returns a copy of arr, stable sorted by the given constraint. Note that false
|
|
* < true, and that `f` may return an array for sort priorities, or undefined if
|
|
* the item should be skipped from the returned result.
|
|
*
|
|
* Note: localeSort() thinks lower case should come before upper case (!!)
|
|
*/
|
|
function sortBy(arr, f) {
|
|
return toArray(arr).filter((ea) => ea != null)
|
|
.map((item) => ({
|
|
item,
|
|
cmp: f(item),
|
|
}))
|
|
.filter((ea) => ea.cmp != null)
|
|
.sort((a, b) => cmp(a.cmp, b.cmp))
|
|
.map((ea) => ea.item);
|
|
}
|
|
function cmp(a, b) {
|
|
// undefined == undefined:
|
|
if (a == null && b == null)
|
|
return 0;
|
|
// undefined should be < defined. We can't use typeof here because typeof null
|
|
// is "object" and typeof undefined = "undefined".
|
|
if (a == null)
|
|
return -1;
|
|
if (b == null)
|
|
return 1;
|
|
const aType = typeof a;
|
|
const bType = typeof b;
|
|
if ((aType === "string" || aType === "symbol") &&
|
|
(bType === "string" || bType === "symbol")) {
|
|
// in German, ä sorts before z, in Swedish, ä sorts after z
|
|
return String(a).localeCompare(String(b));
|
|
}
|
|
return a > b ? 1 : a < b ? -1 : 0;
|
|
}
|
|
function leastBy(haystack, f) {
|
|
let min;
|
|
let result;
|
|
for (const ea of haystack) {
|
|
const val = f(ea);
|
|
if (val != null && (min == null || val < min)) {
|
|
min = val;
|
|
result = ea;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
//# sourceMappingURL=Array.js.map
|