代码拉取完成,页面将自动刷新
// Copyright 2018-20 PJ Engineering and Business Solutions Pty. Ltd. All rights reserved.
package stat
import (
"errors"
"fmt"
)
// ScopeLimit is used to specify a range. Both Start and End are inclusive.
// A nil value means no limit, so a Start of nil means 0
// and an End of nil means no limit.
// The End value must always be equal to or larger than Start.
// Negative values are acceptable. A value of -2 means the second last row.
type ScopeLimit struct {
Start *int
End *int
}
// String implements Stringer interface.
func (r ScopeLimit) String() string {
if r.Start == nil {
if r.End == nil {
return "ScopeLimit:nil—nil"
}
return fmt.Sprintf("ScopeLimit:nil—%d", *r.End)
}
if r.End == nil {
return fmt.Sprintf("ScopeLimit:%d—nil", *r.Start)
}
return fmt.Sprintf("ScopeLimit:%d—%d", *r.Start, *r.End)
}
// NRows returns the number of rows contained by ScopeLimit.
// If End is nil, then length must be provided.
func (r *ScopeLimit) NRows(length ...int) (int, error) {
if len(length) > 0 {
s, e, err := r.Limits(length[0])
if err != nil {
return 0, err
}
return e - s + 1, nil
}
if r.End == nil {
return 0, errors.New("End is nil so length must be provided")
}
var s int
if r.Start != nil {
s = *r.Start
}
if s < 0 || *r.End < 0 {
return 0, errors.New("range invalid")
}
if *r.End < s {
return 0, errors.New("range invalid")
}
return *r.End - s + 1, nil
}
// Limits is used to return the start and end limits of a ScopeLimit
// object for a given Dataframe or Series with length number of rows.
func (r *ScopeLimit) Limits(length int) (s int, e int, _ error) {
if length <= 0 {
return 0, 0, errors.New("limit undefined")
}
if r.Start == nil {
s = 0
} else {
if *r.Start < 0 {
// negative
s = length + *r.Start
} else {
s = *r.Start
}
}
if r.End == nil {
e = length - 1
} else {
if *r.End < 0 {
// negative
e = length + *r.End
} else {
e = *r.End
}
}
if s < 0 || e < 0 {
return 0, 0, errors.New("range invalid")
}
if s > e {
return 0, 0, errors.New("range invalid")
}
if s >= length || e >= length {
return 0, 0, errors.New("range invalid")
}
return
}
// RangeFinite returns a ScopeLimit that has a finite span.
func RangeFinite(start int, end ...int) ScopeLimit {
r := ScopeLimit{
Start: &start,
}
if len(end) > 0 {
r.End = &end[0]
}
return r
}
// IntsToRanges will convert an already (ascending) ordered list of ints to a slice of Ranges.
//
// Example:
//
// import "sort"
// ints := []int{2,4,5,6,8,10,11,45,46}
// sort.Ints(ints)
//
// fmt.Println(IntsToRanges(ints))
// // Output: R{2,2}, R{4,6}, R{8,8}, R{10,11}, R{45,46}
func IntsToRanges(ints []int) []ScopeLimit {
out := []ScopeLimit{}
OUTER:
for i := 0; i < len(ints); i++ {
v1 := ints[i]
j := i + 1
for {
if j >= len(ints) {
// j doesn't exist
v2 := ints[j-1]
out = append(out, ScopeLimit{Start: &v1, End: &v2})
break OUTER
} else {
// j does exist
v2 := ints[j]
prevVal := ints[j-1]
if (v2 != prevVal) && (v2 != prevVal+1) {
out = append(out, ScopeLimit{Start: &v1, End: &prevVal})
i = j - 1
break
}
j++
continue
}
}
}
return out
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。