Skip to content

Instantly share code, notes, and snippets.

@psenger
Last active June 17, 2024 22:55
Show Gist options
  • Save psenger/73cad3f420e3b6c3d8aa728eda796de1 to your computer and use it in GitHub Desktop.
Save psenger/73cad3f420e3b6c3d8aa728eda796de1 to your computer and use it in GitHub Desktop.
[Filter Page/Chunk based on the Page/Chunk Index or Item Index] #JavaScript #Array
//
// Get the Page/Chunk of values based on the Page/Chunk Index of values in an array.
//
// Data looks like [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and you need page 2, the page size is 2.
// Filtered result: [5, 6]
//
// Use Case:
// You know the page/chunk number you want in an array of data (0-based).
// The data is delivered in chunks/pages. Find the appropriate chunk/page
// of data to display.
//
// e.g., when [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] it equates to
// [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] when perPage is 2
// and when pageNumber = 2 (zero-based indexing), it
// will print out the items [5, 6] in index 2 of this array of arrays.
/**
* Filters an array to retrieve a specific page of results.
* Note:
* getPageFilter is approximately 78.23% faster than getPageReduce.
*
* @param {Array} array - The array to filter.
* @param {number} pageNumber - The desired page number.
* @param {number} pageSize - The number of items per page.
* @return {Array} - The filtered array containing the items of the desired page.
*/
const getPageFilter = (array, pageNumber, pageSize) => array.filter((_, index) =>
index >= pageNumber * pageSize && index < (pageNumber + 1) * pageSize
);
/**
* Reduces an array into multiple pages based on the desired page number and page size.
* Note:
* getPageReduce is approximately 359.96% slower than getPageFilter.
*
* @param {Array} array - The original array to be paginated.
* @param {number} pageNumber - The desired page number to retrieve.
* @param {number} pageSize - The number of items per page.
* @returns {Array} - The array containing the items of the desired page number, or an empty array if the page is unavailable.
*/
const getPageReduce = (array, pageNumber, pageSize) => array.reduce((acc, item, index) => {
const pageIndex = Math.floor(index / pageSize);
if (!acc[pageIndex]) {
acc[pageIndex] = [];
}
acc[pageIndex].push(item);
return acc;
}, [])[pageNumber] || [];
// Example usage:
const data = new Array(10).fill(0).map((_, index) => index);
const pageNumber = 2;
const perPage = 2;
console.time('getPageReduce');
console.log(getPageReduce(data, pageNumber, perPage)); // Output: [4, 5]
console.timeEnd('getPageReduce');
console.time('getPageFilter');
console.log(getPageFilter(data, pageNumber, perPage)); // Output: [4, 5]
console.timeEnd('getPageFilter');
//
// Get the Page/Chunk of values based on the Item Index in an array.
//
// Data looks like [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and you need item indexed
// at 4, the page size is 2. Filtered result: [5, 6]
//
// Use Case:
// You know the item index you want in an array of data (0-based);
// The data is delivered in chunks/pages. Find the appropriate chunk/page
// of data to display.
//
// e.g., when [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] it equates to
// [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] when perPage is 2
// and when index = 4 (zero-based indexing), it
// will print out the items [5, 6]
//
/**
* Filters an array to retrieve the page of results containing the specific item index.
* Note:
* findPageByFilter is approximately 81.14% faster than findPageByReduce.
*
* @param {Array} array - The array to filter.
* @param {number} itemIndex - The index of the item to find the page for.
* @param {number} pageSize - The number of items per page.
* @return {Array} - The filtered array containing the page of the specified item.
*/
const findPageByFilter = (array, itemIndex, pageSize) => {
const pageNumber = Math.floor(itemIndex / pageSize);
return array.filter((_, index) =>
index >= pageNumber * pageSize && index < (pageNumber + 1) * pageSize
);
};
/**
* Reduces an array into multiple pages and retrieves the page containing the specific item index.
* Note:
* findPageByReduce is approximately 430.75% slower than findPageByFilter.
*
* @param {Array} array - The original array to be paginated.
* @param {number} itemIndex - The index of the item to find the page for.
* @param {number} pageSize - The number of items per page.
* @returns {Array} - The array containing the items of the desired page, or an empty array if the page is unavailable.
*/
const findPageByReduce = (array, itemIndex, pageSize) => {
const pageNumber = Math.floor(itemIndex / pageSize);
return array.reduce((acc, item, index) => {
const pageIndex = Math.floor(index / pageSize);
if (!acc[pageIndex]) {
acc[pageIndex] = [];
}
acc[pageIndex].push(item);
return acc;
}, [])[pageNumber] || [];
};
// Example usage:
const data = new Array(10).fill(0).map((_, index) => index);
const itemIndex = 4;
const perPage = 2;
console.time('findPageByFilter');
console.log(findPageByFilter(data, itemIndex, perPage)); // Output: [4, 5]
console.timeEnd('findPageByFilter');
console.time('findPageByReduce');
console.log(findPageByReduce(data, itemIndex, perPage)); // Output: [4, 5]
console.timeEnd('findPageByReduce');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment