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

// Already defined on arrays
// Example:
[1, 2, 3, 4].every(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:
[1, 2, 3].forEach(i => console.log(i));

async function forEach(it, f) {
  for await (let v of it) f(v);
}

// Example:
[1, 2, 3].forEach(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

// 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].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