diff --git a/cmd/verysimple/perference.go b/cmd/verysimple/perference.go index 6199bb5..94164d3 100644 --- a/cmd/verysimple/perference.go +++ b/cmd/verysimple/perference.go @@ -108,8 +108,19 @@ func loadPreferences() { return } doWhenUpdateAutoRearrange() + if len(currentUserPreference.CliCmdOrder) == 0 { + return + } if len(currentUserPreference.CliCmdOrder) <= len(cliCmdList) { - cliCmdList = utils.SortByOrder(cliCmdList, currentUserPreference.CliCmdOrder) + var neworder []int + var ei int + cliCmdList, neworder, ei = utils.SortByOrder(cliCmdList, currentUserPreference.CliCmdOrder) + if ei != 0 { + fmt.Println("utils.SortByOrder got ei", ei) + } + if neworder != nil { + currentUserPreference.CliCmdOrder = neworder + } } else { initOrderList() diff --git a/utils/algo.go b/utils/algo.go index 9672a32..4a3b67f 100644 --- a/utils/algo.go +++ b/utils/algo.go @@ -85,13 +85,66 @@ func TrimSlice[T any](a []T, deleteIndex int) []T { //实际上 golang.org/x/exp/slices 的 Delete 函数也可以 } -func SortByOrder[T any](arr []T, order []int) []T { - var result = make([]T, len(arr)) +func SortByOrder[T any](arr []T, order []int) (result []T, neworder []int, erri int) { + //检查长度 + if len(order) != len(arr) { + if len(order) > len(arr) { //这种是有问题的,不应传入;不过,我们整理出一个新的order列表 + + erri = 1 + neworder = make([]int, 0, len(arr)) + + //填上已有的 + for _, v := range order { + if v >= 0 && v < len(arr) && !slices.Contains(neworder, v) { + neworder = append(neworder, v) + } + } + + //补全没有的 + for i := 0; i < len(arr); i++ { + if !slices.Contains(neworder, i) { + neworder = append(neworder, i) + } + } + + order = neworder + } else { + erri = 2 + + //补全没有的 + + for i := 0; i < len(arr); i++ { + if !slices.Contains(order, i) { + order = append(order, i) + } + } + neworder = order + } + } + //检查重复或索引不正确 + for i, v := range order { + order[i] = -1 + if slices.Contains(order, v) || v >= len(arr) || v < 0 { + //有重复,证明该序列无效,重建顺序序列 + erri = 3 + + neworder = make([]int, 0, len(arr)) + + for i := 0; i < len(arr); i++ { + neworder = append(neworder, i) + } + order = neworder + break + } + order[i] = v + } + + result = make([]T, len(arr)) for i, v := range order { result[i] = arr[v] } - return result + return } func MoveItem[T any](arr *[]T, fromIndex, toIndex int) { diff --git a/utils/algo_test.go b/utils/algo_test.go index c2425b0..c6efceb 100644 --- a/utils/algo_test.go +++ b/utils/algo_test.go @@ -4,10 +4,73 @@ import ( "testing" "github.com/e1732a364fed/v2ray_simple/utils" + "golang.org/x/exp/slices" "gonum.org/v1/gonum/stat/combin" ) +func TestSortByOrder(t *testing.T) { + checkResult := func(good, suspect []int) bool { + if len(suspect) != len(good) { + return false + } + m := make(map[int]bool) + for _, v := range suspect { + if m[v] { + return false + } + if !slices.Contains(good, v) { + return false + } + m[v] = true + } + return true + } + x1 := []int{1, 2, 3, 4, 5} + order := []int{5, 4, 1, 2, 3} + result, newo, ei := utils.SortByOrder(x1, order) + t.Log(result, newo, ei) + if !checkResult(x1, result) { + t.Fail() + } + + order = []int{4, 1, 2, 3, 0} + result, newo, ei = utils.SortByOrder(x1, order) + t.Log(result, newo, ei) + if !checkResult(x1, result) { + t.Fail() + } + + order = []int{4, 1, 2, 2, 0} + result, newo, ei = utils.SortByOrder(x1, order) + t.Log(result, newo, ei) + if !checkResult(x1, result) { + t.Fail() + } + + order = []int{4, 1, 2, 0} + result, newo, ei = utils.SortByOrder(x1, order) + t.Log(result, newo, ei) + if !checkResult(x1, result) { + t.Fail() + } + + order = []int{0, 4, 1, 2, 3, 3} + result, newo, ei = utils.SortByOrder(x1, order) + t.Log(result, newo, ei) + if !checkResult(x1, result) { + t.Fail() + } + + order = []int{0, 0, 1, 2, 3, 3} + result, newo, ei = utils.SortByOrder(x1, order) + t.Log(result, newo, ei) + if !checkResult(x1, result) { + t.Fail() + } + +} + const realv1 = "v1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" const realv2 = "v2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" const e1 = "eeeeeeeeeeeeeeeeeeeee1"