UNPKG

locutus

Version:

Locutus other languages' standard libraries to JavaScript for fun and educational purposes

69 lines (68 loc) 2.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.seq = seq; function seq(from, to, by, length_out) { // discuss at: https://locutus.io/r/seq/ // original by: Kevin van Zonneveld (https://kvz.io) // note 1: Generates numeric sequences, similar to common R seq() forms. // note 2: Supported forms: seq(to), seq(from, to), seq(from, to, by), seq(from, to, undefined, length_out). // example 1: seq(5) // returns 1: [1, 2, 3, 4, 5] // example 2: seq(1, 5, 2) // returns 2: [1, 3, 5] // example 3: seq(1, 2, undefined, 5) // returns 3: [1, 1.25, 1.5, 1.75, 2] const start = Number(to === undefined ? 1 : from); const end = Number(to === undefined ? from : to); if (!Number.isFinite(start) || !Number.isFinite(end)) { return []; } const lengthOut = normalizeLengthOut(length_out); if (lengthOut !== null) { if (lengthOut <= 0) { return []; } if (lengthOut === 1) { return [start]; } const step = (end - start) / (lengthOut - 1); const out = []; for (let i = 0; i < lengthOut; i++) { out.push(roundNumber(start + step * i)); } return out; } const step = by === undefined ? (end >= start ? 1 : -1) : Number(by); if (!Number.isFinite(step) || step === 0) { throw new RangeError('seq(): by must be a non-zero finite number'); } if ((end - start) * step < 0) { return []; } const out = []; const epsilon = Math.abs(step) * 1e-12; if (step > 0) { for (let value = start; value <= end + epsilon; value += step) { out.push(roundNumber(value)); } } else { for (let value = start; value >= end - epsilon; value += step) { out.push(roundNumber(value)); } } return out; } function normalizeLengthOut(value) { if (value === undefined) { return null; } const n = Number(value); if (!Number.isFinite(n)) { return null; } return Math.trunc(n); } function roundNumber(value) { return Number.parseFloat(value.toFixed(12)); }