'use strict'; var _getIterator2 = require('babel-runtime/core-js/get-iterator'); var _getIterator3 = _interopRequireDefault(_getIterator2); var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _iterator = require('babel-runtime/core-js/symbol/iterator'); var _iterator2 = _interopRequireDefault(_iterator); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); var _getRange = require('./utils/getRange'); var _zip = require('./utils/zip'); var _some = require('./utils/some'); var _every = require('./utils/every'); var _getReadableStream = require('./utils/getReadableStream'); var _indexOf = require('./utils/indexOf'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @class Harray * @classdesc An infinite array. * @property {Infinity} length - Returns the length of the Harray. (TIP: It's infinite) * @property {Array} cycle - If the harray uses a finite cycle to generate its elements, the cycle will be here, otherwise it will be undefined.<br> * Please see the [Harray.cycle() method]{@link Harray.cycle}. * @param {...Number | Array} element - Every number passed as argument before the formula will be used as an element. You can also pass an array as the first argument instead of multiple elements. * @param {Harray~formula} formula - A formula which will be used to calculate the next element.<br> * If it does not exist the difference between the last two elements will be used as increment value to generate the sequence.<br> * If there's a single element and no formula was provided the sequence will be generated using 1 as increment. * @example * let evensHarray = new Harray(0, 2); * evensHarray.get(2) // -> 4 * evensHarray.get(5) // -> 10 * * let oddsHarray = new Harray(1, 3); * oddsHarray.get(3) // -> 7 * oddsHarray.get(4) // -> 9 * * let binaryHarray = new Harray(1, function(element) { * return element * 2; * }; * * // If your environment supports Proxies you can access elements directly using brackets notation * binaryHarray[1] // -> 2 * binaryHarray[2] // -> 4 * binaryHarray[3] // -> 8 * * // Otherwise you can use `.get(x)` * binaryHarray.get(1) // -> 2 * binaryHarray.get(2) // -> 4 * binaryHarray.get(3) // -> 8 * * let nonUniformHarray = new Harray(1, 10, 22, 24); * nonUniformHarray.get(1) // -> 10 * nonUniformHarray.get(3) // -> 24 * nonUniformHarray.get(4) // -> 26 * nonUniformHarray.get(5) // -> 28 * * let oneItemHarray = new Harray(10); * oneItemHarray.get(0) // -> 10 * oneItemHarray.get(1) // -> 11 * oneItemHarray.get(2) // -> 12 * * let oneItemHarray = new Harray([20, 30]); * oneItemHarray.get(0) // -> 20 * oneItemHarray.get(1) // -> 30 * oneItemHarray.get(2) // -> 40 */ function Harray() { var _this = this; var args = arguments; if (Object.prototype.toString.call(arguments[0]) === '[object Array]') { args = arguments[0]; if (typeof arguments[1] === 'function') { args.push(arguments[1]); } } this.formula = function (el) { return el + 1; }; var formulaExists = false; for (var i = 0; i < args.length; i++) { if (typeof args[i] === 'function') { this.formula = args[i]; formulaExists = true; break; } else { this[i] = args[i]; } } if (args.length >= 2 && !formulaExists) { this.formula = function (el) { return el + args[args.length - 1] - args[args.length - 2]; }; } if (Proxy !== undefined) { return new Proxy(this, { get: function get(target, index) { return _this.get(index); } }); } } Harray.prototype.length = Infinity; /** * This is the formula that will be used to generate the next element in the sequence. * It receives the current element, does whatever you want with it and then returns the next element for the sequence. * @callback Harray~formula * @param {*} element - The element before the one being calculated now. * @param {Number} index - The index for the element being calculated now. * @returns nextElement - The next element for the sequence. * @example * let timesTen = function(element) { * return element * 10; * } * * let harr = new Harray(2, timesTen); * harr.get(0) // -> 2 * harr.get(1) // -> 20 * harr.get(2) // -> 200 * * let twoTimesIndex = function(element, index) { * return index * 2; * } * * let anotherHarr = new Harray(0, twoTimesIndex); * harr.get(0) // -> 0 * harr.get(1) // -> 2 * harr.get(2) // -> 4 * */ /** * Gets the value from an index. * If your environment supports proxies you can directly access values using brackets notation, just like: `myHarray[1]`. * @method * @name Harray#get * @param {Number} index - A value's index. * @returns value - The value of an index. */ Harray.prototype.get = function get(index) { if (this[index] !== undefined) { return this[index]; } else { var lastKey = (0, _keys2.default)(this).length - 2; var result = this[lastKey]; for (var i = lastKey; i < index; i++) { result = this.formula(result, i + 1); this[i + 1] = result; } return this[index] = result; } }; /** * Sets the value for an index. * @method * @name Harray#set * @param {Number} index - An index. * @param {*} index - The value for that index. * @returns harray - The Harray instance in which the value has been set. */ Harray.prototype.set = function set(index, value) { this[index] = value; return this; }; /** * Defines an iterator for Harray. * @method * @returns GeneratorFunctionPrototype */ Harray.prototype[_iterator2.default] = _regenerator2.default.mark(function _callee() { var index, reset; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: index = 0; case 1: if (!true) { _context.next = 8; break; } _context.next = 4; return this.get(index++); case 4: reset = _context.sent; if (reset) { index = 0; } _context.next = 1; break; case 8: case 'end': return _context.stop(); } } }, _callee, this); }); /** Gets the Harray iterator. * @name Harray#getIterator * @method * @returns GeneratorFunctionPrototype */ Harray.prototype.getIterator = _regenerator2.default.mark(function _callee2() { return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: return _context2.delegateYield((0, _getIterator3.default)(this), 't0', 1); case 1: case 'end': return _context2.stop(); } } }, _callee2, this); }); /** * Creates a Harray object which repeats the given cycle. * @method * @name Harray.cycle * @param {...*|Array} cycle - Arguments you want to use to create a cycle or an array of elements. * @returns Harray - A Harray object which repeats the given cycle. * @example * let cycle = Harray.cycle(1, 2, 3); * * cycle.get(2) // -> 3 * cycle.get(3) // -> 1 * cycle.get(4) // -> 2 * * let anotherCycle = Harray.cycle([0, 1]); * anotherCycle.get(1) // -> 1 * anotherCycle.get(2) // -> 0 */ Harray.cycle = function cycle(cycleElements) { var h = new Harray(); h.cycle = arguments.length > 1 ? Array.prototype.slice.call(arguments) : cycleElements; h.get = function (index) { if (this[index] !== undefined) { return this[index]; } else { var result = this.cycle[index % this.cycle.length]; this[index] = result; return result; } }; return h; }; /** * Adds a method to the Harray prototype. * @method * @name Harray.addMethod * @param {String} methodName - The name of the property which will hold the method. * @param {Function} method - The method which will be added to the prototype. * @example * let getDoubleFunction = function(index) { * return this.get(i) * 2; * } * * Harray.addMethod('getDouble', getDoubleFunction); * * let harr = new Harray(1, 2); * harr.getDouble(0) // -> 2 * harr.getDouble(1) // -> 4 */ Harray.addMethod = function addMethod(methodName, method) { Harray.prototype[methodName] = method; }; Harray.addMethod('getRange', _getRange.getRange); Harray.addMethod('zip', _zip.zip); Harray.addMethod('some', _some.some); Harray.addMethod('every', _every.every); Harray.addMethod('getReadableStream', _getReadableStream.getReadableStream); Harray.addMethod('indexOf', _indexOf.indexOf); module.exports = Harray;