DockerERTFF/lib/formatters/collections.js

169 lines
5.0 KiB
JavaScript

module.exports = {
join: function(arr, separator, prop) {
if (!Array.isArray(arr)) return arr;
return arr.map(item => prop ? item[prop] : item).join(separator);
},
first: function(arr) {
if (!Array.isArray(arr)) return arr;
return arr.length ? arr[0] : null;
},
top: function(arr, count) {
if (!Array.isArray(arr)) return arr;
return arr.slice(0, count);
},
last: function(arr, count) {
if (!Array.isArray(arr)) return arr;
if (count) return arr.slice(-count);
return arr[arr.length - 1];
},
where: function(arr, prop, operator, value) {
if (!Array.isArray(arr)) return arr;
return arr.filter(item => {
let val = item[prop];
switch (operator) {
case 'startsWith': return String(val).startsWith(value);
case 'endsWith': return String(val).endsWith(value);
case 'contains': return String(val).includes(value);
case '===': return val === value;
case '!==': return val !== value;
case '==': return val == value;
case '!=': return val != value;
case '<=': return val <= value;
case '>=': return val >= value;
case '<': return val < value;
case '>': return val > value;
};
return true;
});
},
unique: function(arr, prop) {
if (!Array.isArray(arr)) return arr;
if (prop) arr = arr.map(item => item[prop]);
let lookup = [];
return arr.filter(item => {
if (lookup.includes(item)) return false;
lookup.push(item);
return true;
});
},
groupBy: function(arr, prop) {
if (!Array.isArray(arr)) return arr;
return arr.reduce((groups, item) => {
let group = String(item[prop]);
if (!groups[group]) groups[group] = [];
groups[group].push(item);
return groups;
}, {});
},
sort: function(arr, prop) {
if (!Array.isArray(arr)) return arr;
return arr.slice(0).sort((a, b) => {
a = prop ? a && a[prop] : a;
b = prop ? b && b[prop] : b;
if (typeof a == 'string' && typeof b == 'string') {
return a.localeCompare(b);
}
return a < b ? -1 : a > b ? 1 : 0;
});
},
randomize: function(arr) {
if (!Array.isArray(arr)) return arr;
arr = arr.slice(0);
let len = arr.length;
if (len) {
while (--len) {
let rnd = Math.floor(Math.random() * (len + 1));
let val = arr[len];
arr[len] = arr[rnd];
arr[rnd] = val;
}
}
return arr;
},
reverse: function(arr) {
if (!Array.isArray(arr)) return arr;
return arr.slice(0).reverse();
},
count: function(arr) {
if (!Array.isArray(arr)) return arr;
return arr.length;
},
min: function(arr, prop) {
if (!Array.isArray(arr)) return arr;
return arr.reduce((min, num) => {
num = prop ? num[prop] : num;
if (num == null) return min;
num = Number(num);
if (isNaN(num) || !isFinite(num)) return min;
return min == null || num < min ? num : min;
}, null);
},
max: function(arr, prop) {
if (!Array.isArray(arr)) return arr;
return arr.reduce((max, num) => {
num = prop ? num[prop] : num;
if (num == null) return max;
num = Number(num);
if (isNaN(num) || !isFinite(num)) return max;
return max == null || num > max ? num : max;
}, null);
},
sum: function(arr, prop) {
if (!Array.isArray(arr)) return arr;
return arr.reduce((sum, num) => {
num = prop ? num[prop] : num;
if (num == null) return sum;
num = Number(num);
if (isNaN(num) || !isFinite(num)) return sum;
return sum + num;
}, 0);
},
avg: function(arr, prop) {
if (!Array.isArray(arr)) return arr;
let cnt = 0;
return arr.reduce((avg, num) => {
num = prop ? num[prop] : num;
if (num == null) return avg;
num = Number(num);
if (isNaN(num) || !isFinite(num)) return avg;
cnt++;
return avg + num;
}, 0) / cnt;
},
flatten: function(arr, prop) {
if (!Array.isArray(arr)) return arr;
return arr.map(item => item[prop]);
},
keys: function(obj) {
if (typeof obj != 'object') return obj;
return Object.keys(obj);
},
values: function(obj) {
if (typeof obj != 'object') return obj;
return Object.values(obj);
},
};