Skip to content

Instantly share code, notes, and snippets.

@caub
Last active May 15, 2018 18:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caub/da489a286b0098d0fcd799b66a252196 to your computer and use it in GitHub Desktop.
Save caub/da489a286b0098d0fcd799b66a252196 to your computer and use it in GitHub Desktop.
misc fiddles
var cart = (...args) =>
args.reduce((a, b) => [].concat(...a.map(x => b.map(y => x.concat(y)))), [[]]);
// or
// Array.prototype.flatMap=function(fn){return [].concat(...this.map(fn))}
var cart2=(a,b) => a.flatMap(x => b.map(y=>[x,y]));
var cart3=(a,b,c) => a.flatMap(x => b.flatMap(y=> c.flatMap(z=>[x,y, z])));
var cart=(...args) => args.reduce((xs, a) => xs.flatMap(xsi => a.map(ai => [...xsi,ai])), [[]]);
cart(['a', 'b'], [1, 2], [5, 6])
var comb = (len, values, xs) => xs[0].length < len ? comb(len, values, [].concat(...xs.map(x => values.map(v=>x.concat(v))))) : xs;
comb(3, ['a', 'b'], [[]])
// all characters combinaisons of length len of a seed array combos(2,'aA') -> ['aA', 'Aa']
const combos = (len, seed, xs=['']) => xs[0].length < len ? combos(len, seed, [].concat(...xs.map(x => seed.map(c=>x+c)))) : xs;
// for [0,1] simply
var combBinary = len => Array.from({length:2**len},(_,i)=>i.toString(2).padStart(len,0)) // ('0'.repeat(len)+i.toString(2)).slice(-len)
// function compositions (I stands for Identity)
// I(f)(g)(h)(2) or I.f.g(2) instead of f(g(h(2)))
// I(f)[4](2) or I.f[4](2) instead of f(f(f(f(2))))
var I = new Proxy(x=>x, {
get(target,name){
if (isFinite(name)) { // compose function with itself n times
const fn = Array(+name-1).fill(target).reduce( (f,g)=>x=>f(g(x)), x=>x );
return new Proxy(x=>target(fn(x)), this)
}
const fn=eval(name); // bit ugly, fonctions could be beforehand defined in I, or set(target, name, value)
return new Proxy((...x)=>target(fn(...x)), this)
},
apply(target, thisArg, [f, ...other]) {
if (typeof f=="function")
return other.length ? // partial functions
new Proxy((x0, ...x)=>target(f(x0), ...other.map((fi,i)=>fi(x[i]))), this) :
new Proxy((...x)=>target(f(...x)), this); // args must be same length than x for composing them
return target(f,...other); // evaluate
}
});
/*
var f = x=>x*x, g = x=>x*2;
console.log([
I(5),
I(x=>x/2)(x=>x*x)(5),
I(x=>x+2)[2](5),
I(x=>x*2)[10](1),
I((x,y)=>x+y)(5,6),
I((x,y)=>[x,y])(x=>x*x, x=>x)(5,6),
I(([x,y])=>[y,x])(([y,x])=>[x,y])([5,6]),
I.f.g(3),
I[f][g](3),
I(f)(g)(3),
I.g[10](1),
].join('\n'))
*/
// https://jsfiddle.net/crl/rk6f74tw/44/ https://jsfiddle.net/crl/0em4ue4a/
// delay:| |
// evts: | ||| || ||||
// deb: | | |
const debounce = (fn, ms = 500) => {
let timeout;
return (...a) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
fn(...a);
}, ms);
};
}
// delay:| |
// evts: | ||| || ||||
// tho: | | | | |
const throttle = (fn, ms = 500) => {
let d = 0;
return (...a) => {
let _d = Date.now();
if (_d - d > ms) {
fn(...a);
d = _d;
}
}
}
function* fib(n) { for (let i=1, j=1, k=0; k<n; k++){ yield i; [i, j] = [j, i + j]; }};
[...fib(12)]
Array.from({length:10}).reduce(a=>a.concat(a[a.length-2]+a[a.length-1]), [1,1]);
Array.from({0:1,1:1,length:12}).map((x,i,a)=>x || (a[i]=a[i-1]+a[i-2])) // bad but fun
var flatten = a => [].concat(...a.map(x=>Array.isArray(x)?flatten(x):x));
var flatten = a => Array.isArray(a)?[].concat(...a.map(flatten)):a;
var flatten = a => a.reduce((b,c)=>b.concat(Array.isArray(c)?flatten(c):c),[]);
var flatten = a => Array.isArray(a)?a.reduce((b,c)=>b.concat(flatten(c)),[]):a;
var a = [1,[2,[3, [4]]]]
flatten(a)
/((?!172|127|192)(?:\d{1,3}(?:\.\d{1,3}){3}\d{1,3}))/g // match ips not starting with 172,..
var las=s=>s.match(/(\d)\1*/g).map(w=>w.length+w[0]).join``;
las(las(las(las(las('2016')))))
I(las)[5]('2016')// see #composition.js
var P = (resolve=()=>{}, reject=()=>{}) => { // not really a promise, but a thenable
function then(resolve=()=>{}, reject=()=>{}){
try {
var args = resolve(this.args);
var thenBound = then.bind({args});
if (args && typeof args.then === 'function') return args; // should be an instanceof check ideally
return {then: thenBound, catch: reject => thenBound(() => {}, reject)};
} catch(e) {
var catchBound = function(reject=()=>{}) {
reject(e);
return then(undefined, reject);
}.bind({args: e});
return {then: (resolve, reject) => catchBound(reject), catch: catchBound};
}
}
var args = resolve();
return {then, catch: reject => then(() => {}, reject)};
};
var p3 = P().then(() => 4);
P()
.then(() => 6)
.then(x => console.log(3, x))
.then(() => {
throw new Error('oops');
})
.catch(() => console.log('error occured'))
.then(() => p3)
.then(x => console.log(5, x))
function seqs(start, end) {
if (start >= end) return [];
const all = [];
for (let i = start + 1; i < end; i++) { // add pivot points
const lefts = seqs(start, i);
lefts.forEach(left => {
all.push(left.concat([[i, end]]));
});
};
return [[[start, end]]].concat(all);
}
console.log(seqs(0, 2));
function shuffle(a){ // pass a copy of a, because it mutates
for (var i = a.length-1; i > 0; i--) {
const r = Math.floor(i*Math.random());
[a[i], a[r]] = [a[r], a[i]]
}
return a;
}
function shuffle(a){ // pass a copy of a, because it mutates
const r = [];
while(a.length){
r.push(...a.splice(Math.floor(a.length*Math.random()), 1))
}
return r;
}
// generate an ordered sequence of tests, from a list
function testsSeq(tests = [], str='*') {
const ts = tests.reduce((m, s) => {
const [pfx, sfx] = s.split(':');
return m.set(pfx, (m.get(pfx) || new Set()).add(sfx));
}, new Map());
const r = new Set();
str.split(',').forEach(x => {
const [pfx, sfx = '*'] = x.split(':');
if(pfx==='*') {
ts.forEach((v,k) => v.forEach(vi => r.add(k+(vi ? ':'+vi : ''))));
} else if (sfx==='*') {
const v = ts.get(pfx);
if (v) {
v.forEach(vi => {
const str = pfx+(vi ? ':'+vi : '');
r.delete(str); // make sure to remove if needed, so it gets added at the end
r.add(str)
});
}
} else {
const v = ts.get(pfx);
if (v) {
if (v.has(sfx)) {
r.delete(x); // make sure to remove if needed, so it gets added at the end
r.add(x);
v.delete(x);
}
}
}
});
ts.forEach((v,k) => v.forEach(vi => r.add(k+(vi ? ':'+vi : '')))); // add remaining ones
return [...r]
}
console.log('>>', testsSeq(['a', 'b:aa', 'b:rr', 'c:lol', 'd', 'c:bar', 'e'], 'c,*,b'));
console.log('>>', testsSeq(['a', 'b', 'c', 'd', 'e'], 'c,*,b'));
function futch(url, opts={}, onProgress) {
return new Promise( (res, rej)=>{
var xhr = new XMLHttpRequest();
xhr.open(opts.method || 'get', url);
for (var k in opts.headers||{})
xhr.setRequestHeader(k, opts.headers[k]);
xhr.onload = e => res(e.target.responseText);
xhr.onerror = rej;
if (xhr.upload && onProgress)
xhr.upload.onprogress = onProgress; // e.loaded / e.total * 100 ; //e.lengthComputable
xhr.send(opts.body);
});
}
futch('/').then(console.log)
var file = new Blob(Array.from({length:2e5},_=>Math.random()), {type: "octet/stream"});
var fd = new FormData();
fd.append('data', file);
futch('http://httpbin.org/post', {method: 'post', body: fd}, e=>console.log('progress', e))
.then(console.log)
.catch(console.error)
// by value:
var findWally = (o,path=[]) => o&&typeof o=='object' ? [].concat(...Object.entries(o).map(([k,v])=>findWally(v,path.concat(k)))) : o=='wally'?[path]:[];
console.log(...findWally({v:'wally', x:2, wat:{fooo:''}, y:['wally'], o:{o:{k:'wally',i:{g:'wally'},p:'ok'}}}))
// by key:
var findWally = (v,path=[]) => v&&typeof v=='object' ? [].concat(...Object.entries(v).map(([k,v])=>k=='wally'?[path.concat(k)]:findWally(v,path.concat(k)))) : [];
console.log(...findWally({ok:{wally:3}, w:{wally:2}}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment