分页 Javascript 数组

我正在尝试编写一个 Javascript 函数,它以 arraypage_sizepage_number作为参数,并返回一个模拟分页结果的数组:

paginate: function (array, page_size, page_number) {
return result;
}

例如:

array = [1, 2, 3, 4, 5],
page size = 2,
page_number = 2,

函数应该返回: [3, 4]

任何想法都可以。

138409 次浏览

您可以使用 Array.prototype.slice并只提供 (start, end)的参数。

function paginate(array, page_size, page_number) {
// human-readable page numbers usually start with 1, so we reduce 1 in the first argument
return array.slice((page_number - 1) * page_size, page_number * page_size);
}


console.log(paginate([1, 2, 3, 4, 5, 6], 2, 2));
console.log(paginate([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 4, 1));

Another aproach that you can utilize, is using .filter, look:

const paginate = function (array, index, size) {
// transform values
index = Math.abs(parseInt(index));
index = index > 0 ? index - 1 : index;
size = parseInt(size);
size = size < 1 ? 1 : size;


// filter
return [...(array.filter((value, n) => {
return (n >= (index * size)) && (n < ((index+1) * size))
}))]
}


var array = [
{id: "1"}, {id: "2"}, {id: "3"}, {id: "4"}, {id: "5"}, {id: "6"}, {id: "7"}, {id: "8"}, {id: "9"}, {id: "10"}
]




var transform = paginate(array, 2, 5);


console.log(transform) // [{"id":"6"},{"id":"7"},{"id":"8"},{"id":"9"},{"id":"10"}]

可以借助 Array.filter()的第二个参数(数组中正在处理的当前元素的索引)来使用 Array.filter()

您还需要当前选择的页面以及每个页面要显示的条目数,这样就可以找到所需元素的最小和最大索引。

const indexMin = selectedPage * elementsPerPage;
const indexMax = indexMin + elementsPerPage;
const paginatedArray = arrayToPaginate.filter(
(x, index) => index >= indexMin && index < indexMax
);

Updating the selectedPage and/or the elementsPerPage value will allow to return the correct items to display.

使用 Array#slice是预期的答案。

这里我使用 符号迭代器来创建一个 可迭代的

const arr = [1,2,3,4,5,6,7,8,9,10]


function page({arr, pageSize, pageNumber}) {
const start = pageSize*(pageNumber-1)
const end = pageSize*pageNumber
return {
*[Symbol.iterator]() {
for(let i = start; i < arr.length && i < end; i++) {
yield arr[i]
}
}
}
}


console.log([...page({arr, pageSize: 5, pageNumber: 2})])

下面是 reduce()的一个解决方案:

function paginate (arr, size) {
return arr.reduce((acc, val, i) => {
let idx = Math.floor(i / size)
let page = acc[idx] || (acc[idx] = [])
page.push(val)


return acc
}, [])
}


let array = [1, 2, 3, 4, 5]
let page_size = 2
let pages = paginate(array, page_size)


console.log(pages)    // all pages
console.log(pages[1]) // second page

它返回一个页面数组,这样您就可以获取某个页面,或者循环遍历所有页面。

我看到了上面的一个例子,这样做是正确的(种) ,并希望扩展它。

这就是例子。

function paginate(array, page_size, page_number) {
// human-readable page numbers usually start with 1, so we reduce 1 in the first argument
return array.slice((page_number - 1) * page_size, page_number * page_size);
}

这里有一些问题。

1)如果 page_number为0,那么它将尝试在返回空数组的 -1 * page_size处设置起始拆分。因此,page_number attr 的最小值应该是1,除非在函数中处理这种情况,否则不能小于1。

2)拆分的起始索引和结束索引是相同的。因此,返回的是一个空数组。因此,分割应该是:

return array.split(page_number * page_size, page_number * page_size + page_size)

const myArray = [1,2,3,4,5,6,7,8,9,10];


const paginateBad1 = (array, page_size, page_number) => {
return array.slice((page_number - 1) * page_size, page_number * page_size);
};


const paginateBad2 = (array, page_size, page_number) => {
return array.slice(page_number * page_size, page_number * page_size);
};


const paginateGood = (array, page_size, page_number) => {
return array.slice(page_number * page_size, page_number * page_size + page_size);
};


console.log("Bad 1", paginateBad1(myArray, 2, 0));
console.log("Bad 2", paginateBad2(myArray, 2, 1));
console.log("Good", paginateGood(myArray, 2, 1));

嘿,对不起,我来晚了一点,但是我们可以使用 Array.splice(start, end)方法,除了这个更简单

const page = 2
const step = 2;
const start = page * step - step;
const end = start + step;


const array = [1,2,3,4,5,6]
console.log(array.splice(start, end))

function paginate(array, page_size, page_number) {
// human-readable page numbers usually start with 1, so we reduce 1 in the first argument
return array.slice((page_number - 1) * page_size, page_number * page_size);
}
var arr = [1, 2, 3, 4, 5, 6]




const options = {
//page: parseInt(req.query.page) || 1,
page:1,
limit:10
//limit: parseInt(req.query.limit) || 10,
//customLabels: servCustomLabels,
};




let prev_page = 0;
let next_page = 0;
let h_p_p = null;
let h_n_p = null;
let page_count = Math.ceil((arr.length / options.limit));


if (options.page >= page_count ){  // 2 3
next_page = 0;
}
if(options.page >= 1 && options.page < page_count ){
next_page = options.page + 1;
h_n_p = true;
}else{
next_page = 0;
h_n_p = false;
}


if(options.page <= 1 ){
prev_page =0;
h_p_p = false;
}else{
prev_page = options.page -1 ;
h_p_p = true;
}
        

console.log(paginate(arr, 2, 2));
console.log({paginator: {
totalDocs: arr.length,
perPage: options.limit,
pageCount: page_count,
currentPage: options.page,
//slNo: 2,
hasPrevPage: h_p_p,
hasNextPage: h_n_p,
prev: prev_page,
next: next_page
}})

function paginate(arr, PerPage) {
let map = {};
let startPage = 1;
arr.forEach((current) => {
if (map[startPage] && map[startPage].length < PerPage) {
map[startPage].push(current);
}


if (!map[startPage]) {
map[startPage] = [current];
}


if (map[startPage] && map[startPage].length >= PerPage) {
startPage++;
}
});


return map;

}

你可以在这里找到一个例子

下面的例子是使用 ITER-OPS库(我是作者)。

// our inputs...


const array = [1, 2, 3, 4, 5];


const pageSize = 2;
const pageIndex = 1;

最有效的方法是将数组作为迭代进行处理,因此只需遍历一次。

If you never need other pages, then the fastest way is like this:

import {pipe, skip, page} from 'iter-ops';


const p = pipe(
array,
skip(pageSize * pageIndex), // skip pages we don't want
page(pageSize) // create the next page
).first;


console.log(p); //=> [3, 4]

如果你确实需要其他页面,那么你可以这样做:

const p = pipe(
array,
page(pageSize), // get all pages
skip(pageIndex) // skip pages we don't want
).first;


console.log(p); //=> [3, 4]

如果你需要做进一步的处理:

const i = pipe(
array,
page(pageSize), // get all pages
skip(pageIndex), // skip pages we don't want
take(1), // take just one page
// and so on, you can process it further
);


console.log([...i]); //=> [[3, 4]]

下面是使用 Array.from数组,切片的另一个变体

const paginate = (array, n) => {
const pageSize = Math.ceil(array.length / n);
 

return Array.from({ length: pageSize }, (_, index) => {
const start = index * n;
return array.slice(start, start + n);
});
};


How to use it

使用 filter的一个简单解决方案:

function paginate(array, pageIndex, pageSize) {
const first = pageIndex * pageSize
const last = (pageIndex * pageSize) + pageSize
return array.filter((_, index) => {
return first <= index && index < last
})
}
 for (let pageNum = 1; pageNum <= totalPagesCount; pageNum++){
....
const chunk = articles.slice(
(pageNum - 1) * pageSizeNumbered,
pageNum * pageSizeNumbered,
);
.....
}

我会选这样的

const paginateArray =  (array, pageNumber, pageSize) => {
const page = array.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
return page;
};
    

const array = [1, 2, 3, 4, 5];
const pageSize = 2;
const pageNumber = 2;
    

console.log(paginateArray(array, pageNumber, pageSize));