/**
* @module split-into-pile
*/
/**
* @exports split-into-pile.pages
* @constructor
* @param {Object|Array} data - Input the array or object that is going to be used for spliting into pages
* @param {number} size - Specify how much elements can be in one page
* @returns {class} this - Returns this class
*/
class pages {
constructor(data, size) {
if((!!data) && (data.constructor === Array)) {
this.isArray = true;
this.elements = data;
}
else if ((!!data) && (data.constructor === Object)) {
this.isArray = false;
this.elements = data;
} else {
throw createError("Invalid data type. Please use a object or a array of elements for pages!");
}
this.size = size || 10;
this.pages = Math.trunc((this.elements.length + this.size-1) / this.size) || Math.trunc((Object.keys(this.elements).length + this.size-1) / this.size);
}
/**
* Returns the obj/array splited into pages in array format
* @returns {Array} Returns array that contains elements splited into pages
*/
ArrayPages () {
let ArrayListPages = [];
if (this.isArray) {
for (var i = 1; i < this.pages+1; i++) {
if (i === this.pages) ArrayListPages.push(this.elements.slice(i * this.size - this.size));
else ArrayListPages.push(this.elements.slice(i * this.size - this.size, i * this.size));
}
} else {
for (var i = 1; i < this.pages+1; i++) {
if (i === this.pages) ArrayListPages.push(sliceObject(this.elements, i * this.size - this.size));
else ArrayListPages.push(sliceObject(this.elements, i * this.size - this.size, i * this.size));
}
}
return ArrayListPages;
}
/**
* Returns the obj/array splited into pages in object format
* @param {object} options - Options for output
* @param {string} options.keyTemplate - Output with specific keyname (per page)
* @param {Array} options.keySchema - Array that contains every key for every new object entry (page)
* @example - KeyTemplate
* ObjectPages({ keyTemplate: '#{number}' }); // "Number" will be auto replaced with the numeric order of the elements
* @example - KeySchema
* const pages = require('split-into-pile')([2,4,3,5], 2);
* pages.ObjectPages({ keySchema: ['hello', 'example'] }); // Returns {'hello':[2,4], 'example': [3,5]}
* @returns {Object} Returns array that contains elements splited into pages
*/
ObjectPages(options) {
let ObjectPages = {};
options = options || {};
if(options.keyTemplate && options.keySchema) throw createError("You may not use keyTemplate and keySchema at once!");
let keyTemplate = options.keyTemplate || "{number}";
if (keyTemplate.replace('{number}', '') === keyTemplate) throw createError("You have to give a number in template! Example keyTemplate: \"#{number}\"");
if(options.keySchema) {
if ((!!options.keySchem) && (options.keySchem.constructor != Array)) throw createError(`keySchema must be a array containing the same amount of keys as pages : This array/object contains ${this.pages} pages`);
if (options.keySchema.length != this.pages) throw createError(`keySchema array must be the same length as page count : This array/object contains ${this.pages} pages`);
if (this.isArray) {
for (var i = 1; i < this.pages+1; i++) {
if (i === this.pages) ObjectPages[options.keySchema[i-1]] = this.elements.slice(i * this.size - this.size);
else ObjectPages[options.keySchema[i-1]] = this.elements.slice(i * this.size - this.size, i * this.size);
}
} else {
for (var i = 1; i < this.pages+1; i++) {
if (i === this.pages) ObjectPages[options.keySchema[i-1]] = sliceObject(this.elements, i * this.size - this.size);
else ObjectPages[options.keySchema[i-1]] = sliceObject(this.elements, i * this.size - this.size, i * this.size);
}
}
} else {
if (this.isArray) {
for (var i = 1; i < this.pages+1; i++) {
if (i === this.pages) ObjectPages[keyTemplate.replace('{number}', i)] = this.elements.slice(i * this.size - this.size);
else ObjectPages[keyTemplate.replace('{number}', i)] = this.elements.slice(i * this.size - this.size, i * this.size);
}
} else {
for (var i = 1; i < this.pages+1; i++) {
if (i === this.pages) ObjectPages[keyTemplate.replace('{number}', i)] = sliceObject(this.elements, i * this.size - this.size);
else ObjectPages[keyTemplate.replace('{number}', i)] = sliceObject(this.elements, i * this.size - this.size, i * this.size);
}
}
}
return ObjectPages;
}
/**
* Get contents of specific page
* @param {number} page - Page number to get
* @example
* const pages = require('split-into-pile')([2,5,6,8], 2);
* pages.GetPageContent(2); // Returns [6, 8]
* @return {object|array} - Returns one page
*/
GetPageContent(page) {
if(!page) throw createError("Page number not defined. Please provide a page number.")
if(isNaN(page)) throw createError("Invalid page number. Please specify it in numeric format");
if(page > this.pages) throw createError("This page does not exist. You can check if a page exists with .PageExists();");
let pageElements;
if (this.isArray) {
if(page === this.pages) pageElements = this.elements.slice(page * this.size - this.size);
else pageElements = this.elements.slice(page * this.size - this.size, page * this.size);
} else {
if (page === this.pages) pageElements = sliceObject(this.elements, page * this.size - this.size);
else pageElements = sliceObject(this.elements, page * this.size - this.size, page * this.size);
}
return pageElements;
}
/**
* Check if a page exists
* @param {number} page - Page number
* @returns {boolean} - Returns if the page exists
*/
PageExist(page) {
if(!page) throw createError("Page number not defined. Please provide a page number.");
if(isNaN(page)) throw createError("Invalid page number. Please specify it in numeric format");
return Math.trunc((this.elements.length + this.size-1) / this.size) < page;
}
/**
* Check how much pages are there
* @returns {number} - Returns the amount of pages there are
*/
get MaxPages() {
return Math.trunc((this.elements.length + this.size-1) / this.size);
}
}
function createError(msg) {
var err = new Error(msg);
Error.captureStackTrace(err, pages);
return err;
}
function sliceObject(obj, a, b) {
let object = {};
if(!b) Object.keys(obj).slice(a).forEach(key => object[key] = obj[key]);
else Object.keys(obj).slice(a, b).forEach(key => object[key] = obj[key]);
return object;
}
/** test */
module.exports = pages;