我正在尝试用Go创建分页,但我有点困惑。这是我第一次创建分页,因为我还在使用PHP时使用laravel的帮助类。
我尝试过这样的事情:
var totalPages = int(math.Ceil(float64(totalRecords) / float64(recordsPerPage)))
for i := 0; i < totalPages; i++ {
pages[i] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, i+1, limit, i+1)
}
这显示了所有页面,我想创建一些看起来像的东西:
< 1 2 ... 20 24 25 26 27 ... 200 201 >
25是当前页面,201是最后一页。
我还尝试了类似下面的内容但在某些情况下很古怪,比如页面是接近开头还是结尾:
// pages[0] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, 1, limit, 1)
// pages[1] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, 2, limit, 2)
// pages[2] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, 3, limit, 3)
// pages[3] = `<li><a class="more">…</a></li>`
// pages[4] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, page, limit, page)
// pages[5] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, page+1, limit, page+1)
// pages[6] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, page+2, limit, page+2)
// pages[7] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, page+3, limit, page+3)
// pages[8] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, page+4, limit, page+4)
// pages[9] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, page+5, limit, page+5)
// pages[10] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, page+6, limit, page+6)
// pages[11] = `<li><a class="more">…</a></li>`
// pages[12] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, totalPages-1, limit, totalPages-1)
// pages[13] = fmt.Sprintf(`<li><a href="?page=%d&limit=%d">%d</a></li>`, totalPages, limit, totalPages)
所以问题是,我该如何实现这一目标?有图书馆吗?什么是正确的逻辑?
答案 0 :(得分:2)
打破你的问题你会得到它。
你想要的是计算邻居。
package main
import (
"fmt"
)
func main() {
pages(8, 2, 13)
}
func pages(n int, around int, count int) {
first := n - around
if first < 1 {
first = 1
}
last := n + around
if last > count {
last = count
}
if first > 1 {
for i := 1; i <= 2 && i < first; i++ {
fmt.Println(i)
}
if 3 < first {
fmt.Println("...")
}
}
for i := first; i <= last; i++ {
fmt.Println(i)
}
if last < count {
if last <= count-3 {
fmt.Println("...")
}
end := count - 1
if end <= last {
end = last + 1
}
for i := end; i <= count; i++ {
fmt.Println(i)
}
}
}
改进:编号&#34;前缀&#34;和&#34;后缀&#34;页面变量; - )
请参阅:https://play.golang.org/p/wOOO9GmpNV
添加了缩短版本:
package main
import (
"fmt"
)
func main() {
pages(10, 3, 20)
}
func pages(n int, around int, count int) {
var i int
for i = 1; i <= 2 && i<=count; i++ {
fmt.Println(i)
}
if i < n-around {
fmt.Println("...")
i = n - around
}
for ; i <= n+around && i<=count; i++ {
fmt.Println(i)
}
if i < count-1 {
fmt.Println("...")
i = count - 1
}
for ; i <= count; i++ {
fmt.Println(i)
}
}
我们可以通过提供回调轻松包装。请注意,频道非常慢。
package main
import (
"fmt"
)
func main() {
pages(10, 3, 20, func(i int) {
if i < 0 {
fmt.Println("...")
return
}
fmt.Println(i)
})
}
func pages(n int, around int, count int, render func(int)) {
var i int
for i = 1; i <= 2 && i <= count; i++ {
render(i)
}
if i < n-around {
render(-1)
i = n - around
}
for ; i <= n+around && i <= count; i++ {
render(i)
}
if i < count-1 {
render(-1)
i = count - 1
}
for ; i <= count; i++ {
render(i)
}
}
包含所有内容的最新版本(除非错误):
package main
import (
"fmt"
)
func main() {
pages(10, 3, 21,4,4, func(i int) {
if i < 0 {
fmt.Println("...")
return
}
fmt.Println(i)
})
}
func pages(n int, around int, count int,start int, end int, render func(int)) {
var i int
for i = 1; i <= start && i <= count; i++ {
render(i)
}
if i < n-around {
render(-1)
i = n - around
}
for ; i <= n+around && i <= count; i++ {
render(i)
}
if i < count-end+1 {
render(-1)
i = count - end+1
}
for ; i <= count; i++ {
render(i)
}
}
请参阅:https://play.golang.org/p/KfTORNuHY_
这有多好?
注意,如果需要一个数组,可以通过闭包来完成。与渠道相同。
答案 1 :(得分:2)
这是一个简短的实现,它返回您需要呈现的页码:
func pages(cur, max, around int) (r []int) {
for i := cur - around; i <= cur+around; i++ {
if i >= 1 && i <= max {
r = append(r, i)
}
}
for i := 1; i <= around; i++ {
if i < cur-around {
r = append(r, i)
}
if max+1-i > cur+around {
r = append(r, max+1-i)
}
}
sort.Ints(r)
return
}
您需要传递当前页面(cur
),最大页码(max
)以及要在当前页面和列表中列出的邻居数量(around
)列表的末尾
如果彼此相邻的2个页码有差异&gt; 1,您还需要在它们之间呈现...
。
测试它:
fmt.Println(pages(1, 1, 2))
fmt.Println(pages(1, 2, 2))
fmt.Println(pages(1, 3, 2))
fmt.Println(pages(1, 4, 2))
fmt.Println(pages(1, 5, 2))
fmt.Println(pages(1, 9, 3))
fmt.Println(pages(25, 201, 2))
ps := pages(25, 201, 3)
for i, page := range ps {
if i > 0 && ps[i-1]+1 < page {
fmt.Print("... ")
}
fmt.Print(page, " ")
}
输出(在Go Playground上尝试):
[1]
[1 2]
[1 2 3]
[1 2 3 4]
[1 2 3 4 5]
[1 2 3 4 7 8 9]
[1 2 23 24 25 26 27 200 201]
1 2 3 ... 22 23 24 25 26 27 28 ... 199 200 201
sort.Ints()
sort.Ints()
的目的是按递增顺序返回页码。这是必需的,因为第二个循环不按顺序添加数字。
如果我们可以更改它以便第二个循环保持顺序,则不再需要排序。
第二个循环负责从列表的末尾添加页码(开头和结尾)。追加结尾很好(只需要向上),我们将开头添加到另一个切片,其余部分将附加到其中。
这是:
func pages(cur, max, around int) (r []int) {
for i := cur - around; i <= cur+around; i++ {
if i >= 1 && i <= max {
r = append(r, i)
}
}
r2 := make([]int, 0, len(r)+4)
for i := 1; i <= around; i++ {
if i < cur-around {
r2 = append(r2, i)
}
if max-around+i > cur+around {
r = append(r, max-around+i)
}
}
return append(r2, r...)
}
测试和输出是一样的。请在Go Playground上尝试此变体。
如果你想在末尾有不同数量的页面,你可以添加1个额外的参数并使用它添加0复杂度:
func pages(cur, max, around, edge int) (r []int) {
for i := cur - around; i <= cur+around; i++ {
if i >= 1 && i <= max {
r = append(r, i)
}
}
r2 := make([]int, 0, len(r)+2*edge)
for i := 1; i <= edge; i++ {
if i < cur-around {
r2 = append(r2, i)
}
if max-around+i > cur+around {
r = append(r, max-around+i)
}
}
return append(r2, r...)
}
在Go Playground上尝试此变体。