【问题标题】:Paginate Javascript array分页Javascript数组
【发布时间】:2017-08-03 07:37:35
【问题描述】:

我正在尝试编写一个 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]

任何想法都将不胜感激。

【问题讨论】:

  • [3, 4] 相对于所有其他变量代表什么?这是您明确解释的关键
  • 使用Array.slice -> array.slice((page_number - 1) * page_size, page_size)(这样应该可以)
  • @DarrenSweeney 如果将数组划分为“pages”,我们将得到 3 个页面,每个页面的大小最多为 2:[1, 2][3, 4][5]。在这种情况下,第 2 页将是 [3, 4]

标签: javascript arrays pagination


【解决方案1】:

您可以使用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));

【讨论】:

  • @casraf:你先减少page_number,然后在page_number + 1 切片时加1。我不明白这背后的逻辑是什么。我可能看起来很幼稚,但你能解释一下吗?
  • 它可以按照你想要的任何顺序来完成,但是 slice 需要一个 0-index 编号(从第 0 项到第 n 的切片),并且链接和其他人类可读格式中的页面大小通常从页面开始1 而不是 0。由于我们在前端从 1 开始,但实际上我们使用 0,所以我会减少它并在相关时间增加它。你可以很容易地只减少第一个参数中的 page_number 而不是第二个
【解决方案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

它返回一个页面数组,这样你就可以得到某个页面,或者遍历所有页面。

【讨论】:

  • 两个参数 FTW!
【解决方案3】:

我在上面看到了一个正确(有点)执行此操作的示例,并希望对其进行扩展。

这就是例子。

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,除非你在函数中处理这种情况,否则永远不会少。

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));

【讨论】:

    【解决方案4】:

    您可以利用的另一种方法是使用 .filter,看:

    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"}] 
    

    【讨论】:

      【解决方案5】:

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

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

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

      更新 selectedPage 和/或 elementsPerPage 值将允许返回要显示的正确项目。

      【讨论】:

        【解决方案6】:

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

        这里我使用Symbol.iterator 创建一个iterable

        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})])

        【讨论】:

          【解决方案7】:

          这是另一个使用Array.fromArray.slice 的变体

          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);
            });
          };
          
          

          【讨论】:

            【解决方案8】:

            对不起,我来晚了,但我们可以使用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))
            

            【讨论】:

              【解决方案9】:

              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
                              }})

              【讨论】:

                【解决方案10】:
                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;
                

                }

                you will find an example on this link

                【讨论】:

                  【解决方案11】:

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

                  // our inputs...
                  
                  const array = [1, 2, 3, 4, 5];
                  
                  const pageSize = 2;
                  const pageIndex = 1;
                  

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

                  如果你永远不需要其他页面,那么最快的方法是这样的:

                  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]]
                  

                  【讨论】:

                    【解决方案12】:

                    使用filter的简单解决方案:

                    function paginate(array, pageIndex, pageSize) {
                      const first = pageIndex * pageSize
                      const last = (pageIndex * pageSize) + pageSize
                      return array.filter((_, index) => {
                        return first <= index && index < last
                      })
                    }
                    

                    【讨论】:

                      猜你喜欢
                      • 2015-09-09
                      • 1970-01-01
                      • 1970-01-01
                      • 2022-01-19
                      • 1970-01-01
                      • 2012-10-04
                      • 2016-03-10
                      相关资源
                      最近更新 更多