package helpers
import (
"fmt"
"math"
"slices"
"unicode"
)
type AsciiSearchValues struct {
set [2 ]uint64
}
func NewAsciiSearchValues (vals string ) AsciiSearchValues {
sv := AsciiSearchValues {}
for i := 0 ; i < len (vals ); i ++ {
c := vals [i ]
if c > unicode .MaxASCII {
panic (fmt .Errorf ("non-ascii value found in ascii search values: %s" , vals ))
}
idx := c / 64
shift := c % 64
sv .set [idx ] |= 1 << shift
}
return sv
}
func (s AsciiSearchValues ) IndexOfAny (chars []rune ) int {
for i := 0 ; i < len (chars ); i ++ {
c := chars [i ]
if c > unicode .MaxASCII {
continue
}
idx := c / 64
shift := c % 64
if s .set [idx ]&(1 <<shift ) != 0 {
return i
}
}
return -1
}
func (s AsciiSearchValues ) IndexOfAnyExcept (chars []rune ) int {
for i := 0 ; i < len (chars ); i ++ {
c := chars [i ]
if c > unicode .MaxASCII {
return i
}
idx := c / 64
shift := c % 64
if s .set [idx ]&(1 <<shift ) == 0 {
return i
}
}
return -1
}
func (s AsciiSearchValues ) LastIndexOfAny (chars []rune ) int {
panic ("not implemented" )
}
func (s AsciiSearchValues ) LastIndexOfAnyExcept (chars []rune ) int {
panic ("not implemented" )
}
type RuneSearchValues struct {
vals []rune
}
func newRuneSearchValues(vals []rune ) RuneSearchValues {
return RuneSearchValues {vals : vals }
}
func NewRuneSearchValues (vals string ) RuneSearchValues {
return newRuneSearchValues ([]rune (vals ))
}
func (s RuneSearchValues ) IndexOfAny (chars []rune ) int {
return IndexOfAny (chars , s .vals )
}
func (s RuneSearchValues ) IndexOfAnyExcept (chars []rune ) int {
return IndexOfAnyExcept (chars , s .vals )
}
func (s RuneSearchValues ) LastIndexOfAny (chars []rune ) int {
panic ("not implemented" )
}
func (s RuneSearchValues ) LastIndexOfAnyExcept (chars []rune ) int {
panic ("not implemented" )
}
type StringSearchValues struct {
vals [][]rune
ignoreCase bool
shortestVal int
firstChars RuneSearchValues
}
func NewStringSearchValues (vals [][]rune , ignoreCase bool ) StringSearchValues {
min := math .MaxInt
firstLetters := make ([]rune , 0 , len (vals ))
for _ , val := range vals {
if min > len (val ) {
min = len (val )
}
if !slices .Contains (firstLetters , val [0 ]) {
firstLetters = append (firstLetters , val [0 ])
if ignoreCase && val [0 ] != unicode .ToUpper (val [0 ]) {
firstLetters = append (firstLetters , unicode .ToUpper (val [0 ]))
}
}
}
return StringSearchValues {
vals : vals ,
ignoreCase : ignoreCase ,
shortestVal : min ,
firstChars : newRuneSearchValues (firstLetters ),
}
}
func (s StringSearchValues ) StartsWith (chars []rune ) int {
panic ("not implemented" )
}
func (s StringSearchValues ) StartsWithIgnoreCase (chars []rune ) int {
panic ("not implemented" )
}
func (s StringSearchValues ) IndexOfAny (in []rune ) int {
end := len (in ) - s .shortestVal
for i := 0 ; i <= end ; i ++ {
j := s .firstChars .IndexOfAny (in [i :])
if j < 0 {
return -1
}
j += i
for _ , val := range s .vals {
if len (in )-j >= len (val ) && Equals (in , j , len (val ), val ) {
return j
}
if s .ignoreCase && len (in )-j >= len (val ) && EqualsIgnoreCase (in , j , len (val ), val ) {
return j
}
}
i = j
}
return -1
}
The pages are generated with Golds v0.8.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .