Last active
March 26, 2020 10:09
-
-
Save Mandorlo/2e07ba71000382f477a4cad004a050f8 to your computer and use it in GitHub Desktop.
This file contains 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
/* ======================================================= */ | |
/* OPS SUR LES ENSEMBLES */ | |
/* ======================================================= */ | |
function xor(arr1, arr2, fn = null) { | |
let arr = [] | |
let xor1 = identity(arr1) | |
let xor2 = identity(arr2) | |
if (fn && typeof fn == 'string') { | |
xor1 = arr1.map(el => el[fn]) | |
xor2 = arr2.map(el => el[fn]) | |
} else if (fn) { | |
xor1 = arr1.map(fn) | |
xor2 = arr2.map(fn) | |
} | |
for (let i = 0; i < arr1.length; i++) { | |
if (xor2.indexOf(xor1[i]) < 0) arr.push(arr1[i]) | |
} | |
for (let i = 0; i < arr2.length; i++) { | |
if (xor1.indexOf(xor2[i]) < 0) arr.push(arr2[i]) | |
} | |
return arr | |
} | |
// renvoie l'array intersection de @arr1 et @arr2 | |
function intersection(arr1, arr2) { | |
let res = [] | |
for (let o of arr1) { | |
if (arr2.indexOf(o) > -1) res.push(o) | |
} | |
return res | |
} | |
// renvoie la différence (au sens d'ensembles) o2 - o1 | |
// càd renvoie un objet avec les paires key/val de o2 qui ne sont pas dans o1 | |
// si strict = true on compare key et val, sinon on ne compare que la présence de key dans o1 | |
function objDiff(o2, o1, strict = true) { | |
let o = {} | |
for (let attr in o2) { | |
if (o1[attr] != o2[attr] || (!strict && !o1.hasOwnProperty(attr))) { | |
o[attr] = o2[attr] | |
} | |
} | |
return o | |
} |
This file contains 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
/** | |
* Returns the element in o at the corresponding path | |
* e.g. | |
* - o = {a:1, b: {c:2, d:3} } | |
* - path = "/b/c" | |
* getPath(o, path) --> 2 | |
* | |
* @param object o this is a javascript object | |
* @param string|array path describes a path in the object o | |
* @param optional string sep is the path separator | |
* @param optional any retval is the value to return if path is not found in o | |
* | |
* @return any : returns the sub-object in o at the right path if it exists | |
* @return any : returns retval if path cannot be found in o | |
* | |
*/ | |
function getPath(o, path, sep = '/', retval = false) { | |
if (typeof path === 'string') { | |
if (!path.length) return o; | |
// here below we remove sep characters at the beginning and end of path string | |
// and we deduplicate consecutive sep characters | |
path = path.replace(new RegExp(`^\\${sep}+|\\${sep}+$`, "g"), '').replace(new RegExp(`\\${sep}+`, "g"), sep); | |
path = path.split(sep); | |
} | |
if (path.length == 0) return o; | |
return (path[0] in o) ? getPath(o[path[0]], path.slice(1), sep, retval) : retval; | |
} | |
function uniq(arr) { | |
let unique = [] | |
for (let el of arr) { | |
if (unique.indexOf(el) < 0) unique.push(el) | |
} | |
return unique | |
} | |
/** | |
* Returns only unique values of loo | |
* if attr != null returns only unique values comparing elements based on attribute attr | |
* | |
* @param array of objects loo a list of elements (usually objects but not mandatory) | |
* @param string attr the attribute to check unicity. if attr == null, checks elements of loo directly | |
* | |
* @return loo with only unique elements in terms of o[attr] | |
*/ | |
function uniqBy(loo, attr = null) { | |
let mem = []; | |
if (!attr) return loo.filter(el => { | |
if (mem.includes(el)) return false; | |
mem.push(el); return true; | |
}); | |
return loo.filter(el => { | |
if (mem.includes(el[attr])) return false; | |
mem.push(el[attr]); return true; | |
}) | |
} | |
Array.prototype.sortBy = function(fn) { | |
if (typeof fn == 'string') fn = (el) => el[fn]; | |
return this.sort((a,b) => { | |
if (fn(a) < fn(b)) return -1; | |
return 1 | |
}) | |
} | |
Array.prototype.splitBy = function(fn) { | |
let ids = [] | |
let res = [] | |
for (let i = 0; i < this.length; i++) { | |
let id = fn(this[i]) | |
let n = ids.indexOf(id) | |
if (n > -1) { | |
res[n].push(this[i]) | |
} else { | |
ids.push(id) | |
res.push([this[i]]) | |
} | |
} | |
return res | |
} | |
function identity(arr) { | |
if (!arr || typeof arr.map != 'function') return arr; | |
return arr.map(el => el) | |
} | |
// arr est un array d'objet. | |
// mapAttr renvoie un nouvel array des mêmes objets mais avec l'attribut attr mis à jour avec fn(el) | |
function mapAttr(arr, attr, fn) { | |
return arr.map(el => { | |
el[attr] = fn(el) | |
return el | |
}) | |
} |
This file contains 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
/* ======================================================= */ | |
/* MATH */ | |
/* ======================================================= */ | |
Array.prototype.sum = function() { | |
return this.reduce((a,b) => a+b, 0) | |
} | |
Array.prototype.mean = function() { | |
if (this.length == 0) return 0; | |
return this.reduce((a,b) => a+b, 0) / this.length | |
} | |
Array.prototype.square = function() { | |
return this.map(el => Math.pow(el, 2)) | |
} | |
Array.prototype.variance = function() { | |
return this.square().mean() - Math.pow(this.mean(), 2) | |
} | |
/* ======================================================= */ | |
/* OBJECTS MANIPULATIONS */ | |
/* ======================================================= */ | |
// traverse un objet profondément et dès que @condition(attr, val, tree) est vérifiée, on renvoie result(attr, val, tree) | |
export function traverse(obj, condition, result, tree = {}) { | |
let debug = false | |
let new_obj = {} | |
if (debug) console.log("traversing OBJ : ", obj) | |
if (typeof obj == 'object' && !obj.length) { | |
if (debug) console.log("OBJ ok") | |
for (let attr in obj) { | |
if (condition(attr, obj[attr], tree)) { | |
new_obj[attr] = result(attr, obj[attr], tree) | |
if (debug) console.log("condition passed for " + attr, new_obj[attr], tree) | |
} else { | |
if (debug) console.log("going to traverse one level deeper on " + attr) | |
new_obj[attr] = traverse(obj[attr], condition, result, {val: attr, parent: tree}) | |
} | |
} | |
return new_obj | |
} else if (condition(null, obj, tree)) { | |
if (debug) console.log('not obj but condition true. Returning : ', result(null, obj, tree)) | |
return result(null, obj, tree) | |
} else { | |
if (debug) console.log('not obj. Returning : ', obj) | |
return obj | |
} | |
} | |
/* ======================================================= */ | |
/* CONVERSIONS */ | |
/* ======================================================= */ | |
// joinObj({a:1,b:2}, '&', '=') = "a=1&b=2" | |
function joinObj(o, sep_attr = '&', sep_val = '=') { | |
let arr = [] | |
for (let attr in o) { | |
arr.push(attr + sep_val + o[attr]) | |
} | |
return arr.join(sep_attr) | |
} | |
function obj2arr(o, add_key = '') { | |
let arr = [] | |
for (let attr in o) { | |
if (add_key != '') o[attr][add_key] = attr; | |
arr.push(o[attr]) | |
} | |
return arr | |
} | |
// renvoie un objet à partir d'un array | |
function map2Obj(arr, fn_id, fn_val) { | |
let o = {} | |
for (let i = 0; i < arr.length; i++) { | |
let key; | |
if (typeof fn_id == 'string') key = arr[i][fn_id]; | |
else key = fn_id(arr[i]); | |
let val; | |
if (typeof fn_val == 'string') val = arr[i][fn_val]; | |
else val = fn_val(arr[i]) | |
o[key] = val | |
} | |
return o | |
} |
This file contains 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
/** | |
* Checks if a string is a valid email | |
*/ | |
function checkEmail(s) { | |
return /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(s); | |
} | |
function normalize(s) { | |
return s.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9\-\_]/g, "") | |
} | |
function basename(path) { | |
return path.split('/').reverse()[0]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment