Underdash

Just copy/paste what’cha need

// Already defined on arrays
// Example:
[1, 2].concat([3, 4]);
// returns [1, 2, 3, 4]
function* concat(...its) {
  for (let it of its) yield* it;
}

// Example:
concat([1, 2], [3, 4], [5, 6]);
// returns [1, 2, 3, 4, 5, 6]
async function* concat(...its) {
  for await (let it of its) yield* it;
}

// Example:
concat([1, 2], [3, 4], [5, 6]);
// returns [1, 2, 3, 4, 5, 6]
Back to top
function dropWhile(arr, f) {
  let ok = false;
  return arr.filter(e => ok || (ok = !f(e)));
};

// Example:
dropWhile([1, 2, 3, 4], e => e < 3);
// returns [3, 4]
function* dropWhile(it, f) {
  it = it[Symbol.iterator]();
  for (let v of it)
    if (!f(v)) {
      yield v;
      break;
    }
  yield* it;
}

// Example:
dropWhile([1, 2, 3, 4], e => e < 3);
// returns [3, 4]
async function* dropWhile(it, f) {
  it = it[Symbol.iterator]();
  for await (let v of it)
    if (!f(v)) {
      yield v;
      break;
    }
  yield* it;
}

// Example:
dropWhile([1, 2, 3, 4], e => e < 3);
// returns [3, 4]
Back to top
function equals(arr1, arr2) {
  if (arr1.length !== arr2.length) return false;
  for (let i in arr1) {
    if (arr1[i] !== arr2[i]) return false;
  }
  return true;
}

// Example:
equals([1,2,3,'hello'], [1,2,3,'hello']);
// returns true
function equals(it1, it2) {
  it1 = it1[Symbol.iterator]();
  it2 = it2[Symbol.iterator]();
  while (true) {
    let i1 = it1.next(), i2 = it2.next();
    if (i1.value !== i2.value) return false;
    if (i1.done || i2.done) return i1.done && i2.done;
  }
}

// Example:
equals([1,2,3,'hello'], [1,2,3,'hello']);
// returns true
async function equals(it1, it2) {
  it1 = it1[Symbol.iterator]();
  it2 = it2[Symbol.iterator]();
  while (true) {
    let i1 = await it1.next(), i2 = await it2.next();
    if (i1.value !== i2.value) return false;
    if (i1.done || i2.done) return i1.done && i2.done;
  }
}

// Example:
equals([1,2,3,'hello'], [1,2,3,'hello']);
// returns true
Back to top
// Already defined on arrays
// Example:
[1, 2, 3, 4].every(e => e < 5);
// returns true
function every(it, f) {
  let ok = true;
  for (let v of it) ok = ok && f(v);
  return ok;
}

// Example:
every([1, 2, 3, 4], e => e < 5);
// returs true
async function every(it, f) {
  let ok = true;
  for await (let v of it) ok = ok && f(v);
  return ok;
}

// Example:
every([1, 2, 3, 4], e => e < 5);
// returs true
Back to top
// Already defined on arrays
// Example:
[1, 2, 3].fill(0);
// returns [0, 0, 0]
function* fill(it, v) {
  for (let _ of it) yield v;
}

// Example:
fill([1, 2, 3], 0);
// returns [0, 0, 0]
async function* fill(it, v) {
  for await (let _ of it) yield v;
}

// Example:
fill([1, 2, 3], 0);
// returns [0, 0, 0]
Back to top
// Already defined on arrays
// Example:
[1, 2, 3, 4].filter(e => e % 2 == 0);
// returns [2, 4]
function* filter(it, f) {
  for (let v of it) {
    if (!f(v)) continue;
    yield v;
  }
}

// Example:
filter([1, 2, 3, 4], e => e % 2 == 0);
// returns [2, 4]
async function* filter(it, f) {
  for await (let v of it) {
    if (!f(v)) continue;
    yield v;
  }
}

// Example:
filter([1, 2, 3, 4], e => e % 2 == 0);
// returns [2, 4]
Back to top
// Already defined on arrays
// Example:
[1, 2, 3, 4].find(e => e > 2);
// returns 3
function find(it, f) {
  for (let v of it)
    if (f(v)) return v; 
}

// Example:
find([1, 2, 3, 4], e => e > 2);
// returns 3
async function find(it, f) {
  for await (let v of it)
    if (f(v)) return v; 
}

// Example:
find([1, 2, 3, 4], e => e > 2);
// returns 3
Back to top
function flatten(arr) {
  return Array.prototype.concat.apply([], arr);
}

// Example:
flatten([1, [2, 3], [[4]]]);
// returns [1, 2, 3, [4]]
function* flatten(it) {
  for (let v of it) {
    if (v[Symbol.iterator])
      yield* v;
    else
      yield v;
  }
}

// Example:
flatten([1, [2, 3], [[4]]]);
// returns [1, 2, 3, [4]]
async function* flatten(it) {
  for await (let v of it) {
    if (v[Symbol.iterator])
      yield* v;
    else
      yield v;
  }
}

// Example:
flatten([1, [2, 3], [[4]]]);
// returns [1, 2, 3, [4]]
Back to top
// Already defined on arrays
// Example:
[1, 2, 3].forEach(i => console.log(i));
function forEach(it, f) {
  for (let v of it) f(v);
}

// Example:
forEach([1, 2, 3], i => console.log(i));
async function forEach(it, f) {
  for await (let v of it) f(v);
}

// Example:
forEach([1, 2, 3], i => console.log(i));
Back to top
function intersection(a1, a2, eq) {
  return a1.filter(e1 => a2.some(e2 => eq(e1, e2)));
}

// Example:
intersection([1, 2, 3], [2, 4, 6], (a, b) => a === b);
// returns [2]
Back to top
// Already defined on arrays
// Example:
[1, 2, 3].map(e => e*e)
// returns [1, 4, 9]
function* map(it, f) {
  for (let v of it) 
    yield f(v);
}

// Example:
map([1, 2, 3], e => e*e)
// returns [1, 4, 9]
async function* map(it, f) {
  for await (let v of it) 
    yield f(v);
}

// Example:
map([1, 2, 3], e => e*e)
// returns [1, 4, 9]
Back to top
function max(arr, gt) {
  return arr.slice(1).reduce((max, cur) => gt(max, cur)?max:cur, arr[0]);
}

// Example:
max([{i:0,v:1},{i:1,v:9},{i:2,v:-2}], (a, b) => a.v > b.v);
// returns {i:1, v:9}
function max(it, gt) {
  let max = undefined;
  for(let v of it) {
    if(!max) {
      max = v;
      continue;
    }
    max = gt(max, v)?max:v;
  }
  return max;
}

// Example:
max([{i:0,v:1},{i:1,v:9},{i:2,v:-2}], (a, b) => a.v > b.v);
// returns {i:1, v:9}
async function max(it, gt) {
  let max = undefined;
  for await (let v of it) {
    if(!max) {
      max = v;
      continue;
    }
    max = gt(max, v)?max:v;
  }
  return max;
}

// Example:
max([{i:0,v:1},{i:1,v:9},{i:2,v:-2}], (a, b) => a.v > b.v);
// returns {i:1, v:9}
Back to top
function min(arr, gt) {
  return arr.slice(1).reduce((min, cur) => gt(min, cur)?cur:min, arr[0]);
}

// Example:
min([{i:0,v:1},{i:1,v:9},{i:2,v:-2}], (a, b) => a.v > b.v);
// returns {i:2, v:-2}
function min(it, gt) {
  let min = undefined;
  for(let v of it) {
    if(!min) {
      min = v;
      continue;
    }
    min = gt(min, v)?v:min;
  }
  return min;
}

// Example:
min([{i:0,v:1},{i:1,v:9},{i:2,v:-2}], (a, b) => a.v > b.v);
// returns {i:2, v:-2}
async function min(it, gt) {
  let min = undefined;
  for await (let v of it) {
    if(!min) {
      min = v;
      continue;
    }
    min = gt(min, v)?v:min;
  }
  return min;
}

// Example:
min([{i:0,v:1},{i:1,v:9},{i:2,v:-2}], (a, b) => a.v > b.v);
// returns {i:2, v:-2}
Back to top
function range(start, len) {
  return new Array(len).fill().map((_, i) => start + i);
};

// Example:
range(-5, 10);
// returns [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
function* range(start, len) {
  for (;len > 0; len--) yield start++;
}

// Example:
range(-5, 10);
// returns [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
async function* range(start, len) {
  for await (;len > 0; len--) yield start++;
}

// Example:
range(-5, 10);
// returns [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
Back to top
// Already defined on arrays
// Example:
[1, 2, 3].reduce((acc, cur) => acc + cur, 0);
// returns 6
function reduce(it, f, v0) {
  for(let v of it) v0 = f(v0, v);
  return v0;
}

// Example:
reduce([1, 2, 3], (acc, cur) => acc + cur, 0);
// returns 6
async function reduce(it, f, v0) {
  for await (let v of it) v0 = f(v0, v);
  return v0;
}

// Example:
reduce([1, 2, 3], (acc, cur) => acc + cur, 0);
// returns 6
Back to top
function shuffle(arr) {
  const a = arr.slice();
  for (let i = a.length; i; i--) {
    let j = Math.floor(Math.random() * i);
    [a[i - 1], a[j]] = [a[j], a[i - 1]];
  }
  return a;
}

// Example:
shuffle([1, 2, 3, 4])
// might return [2, 4, 1, 3] (or something)
Back to top
// Already defined on arrays
// Example:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].slice(5, 9);
// returns [6, 7, 8, 9]
function* slice(it, start = 0, end = Number.POSITIVE_INFINITY) {
  it = it[Symbol.iterator]();
  for(; start > 0; start--, end--) it.next();
  for(let v of it) 
    if(end-- > 0)
      yield v;
    else
      break;
}

// Example:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].slice(5, 9);
// returns [6, 7, 8, 9]
function* slice(it, start, end) {
  it = it[Symbol.iterator]();
  for(; start > 0; start--, end--) await it.next();
  for await (let v of it) 
    if(end-- > 0)
      yield v;
    else
      break;
}

// Example:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].slice(5, 9);
// returns [6, 7, 8, 9]
Back to top
// Already defined on arrays
// Example:
[1, 2, 3, 4].some(e => e % 3 === 0);
// returns true
function some(it, f) {
  for(let v of it) 
    if(f(v)) return true;
  return false;
}

// Example:
some([1, 2, 3, 4], e => e % 3 === 0);
// returns true
async function some(it, f) {
  for await (let v of it) 
    if(f(v)) return true;
  return false;
}

// Example:
some([1, 2, 3, 4], e => e % 3 === 0);
// returns true
Back to top
function takeWhile(arr, f) {
  let ok = true;
  return arr.filter(e => ok && (ok = f(e)));
}

// Example:
takeWhile([1, 2, 3, 4], e => e < 3);
// returns [1, 2]
function* takeWhile(it, f) {
  for (let v of it) {
    if (!f(v)) return;
    yield v;
  }
}

// Example:
takeWhile([1, 2, 3, 4], e => e < 3);
// returns [1, 2]
async function* takeWhile(it, f) {
  for await (let v of it) {
    if (!f(v)) return;
    yield v;
  }
}

// Example:
takeWhile([1, 2, 3, 4], e => e < 3);
// returns [1, 2]
Back to top
function unique(arr, f) {
  const vArr = arr.map(f);
  return arr.filter((_, i) => vArr.indexOf(vArr[i]) === i);
}

// Example:
unique([{i:0,v:2},{i:1,v:3},{i:2,v:2}], e => e.v);
// returns [{i:0,v:2},{i:1,v:3}]
function* unique(it, f) {
  const buffer = [];
  for (let v of it) {
    const fv = f(v);
    if (buffer.indexOf(fv) !== -1) continue;
    buffer.push(fv);
    yield v;
  }
}

// Example:
unique([{i:0,v:2},{i:1,v:3},{i:2,v:2}], e => e.v);
// returns [{i:0,v:2},{i:1,v:3}]
async function* unique(it, f) {
  const buffer = [];
  for await (let v of it) {
    const fv = f(v);
    if (buffer.indexOf(fv) !== -1) continue;
    buffer.push(fv);
    yield v;
  }
}

// Example:
unique([{i:0,v:2},{i:1,v:3},{i:2,v:2}], e => e.v);
// returns [{i:0,v:2},{i:1,v:3}]
Back to top
function zip(...arrs) {
  const resultLength = Math.min(...arrs.map(a => a.length));
  return new Array(resultLength)
    .fill(0)
    .map((_, i) => arrs.map(a => a[i]));
}

// Example:
zip([1, 2, 3], [4, 5, 6], [7, 8, 9]);
// returns [[1,4,7], [2,5,8], [3,6,9]]
function* zip(...its) {
  its = its.map(it => it[Symbol.iterator]());
  while(true) {
    const vs = its.map(it => it.next());
    if (vs.some(v => v.done)) return;
    yield vs.map(v => v.value);
  }
}

// Example:
zip([1, 2, 3], [4, 5, 6], [7, 8, 9]);
// returns [[1,4,7], [2,5,8], [3,6,9]]
async function* zip(...its) {
  its = its.map(it => it[Symbol.iterator]());
  while(true) {
    const vs = await Promise.all(its.map(it => it.next()));
    if (vs.some(v => v.done)) return;
    yield vs.map(v => v.value);
  }
}

// Example:
zip([1, 2, 3], [4, 5, 6], [7, 8, 9]);
// returns [[1,4,7], [2,5,8], [3,6,9]]
Back to top