遍历切片并修改为二维数组

loop through slices and amend into a 2D array

我有 17 (len(inputStartSlice)) 个索引切片,它们将构成一系列字符串切片。目前,当我有 17 个需要循环进入单个二维字符串数组时,我的代码只生成一个字符串片段(单个输入,因为我对位置进行硬编码,如下所示)。

var inputSlices []string
var inputStartSlice []int
var inputEndSlice []int
var input []string
var inputs [][]string


for v, line := range inputSlices {
  if strings.Contains(line, "{") {
    inputStartSlice = append(inputStartSlice, v)
  }
  if strings.Contains(line, "}") {
    inputEndSlice = append(inputEndSlice, v+1)
  }
}

input = inputSlice[inputStartSlice[3]:inputEndSlice[3]]

inputs = append(inputs, input)
fmt.Println(inouts)

Playground

有没有更好的方法来做到这一点?我敢肯定,如果有人可以帮助我理解更好的方法或详细说明如何解决我目前遇到的问题..

我已经用更惯用的方式重写了您的代码。查看评论以获取解释。此代码有效,但正如 mpx 所建议的那样,为了处理任何自定义格式,您必须编写标记器和词法分析器以确保正确解析所有内容并处理每个可能的语法错误。

package main

import (
    "fmt"
    "log"
    "strings"

    "golang.org/x/exp/slices"
)

func main() {

    var codeSlices = []string{
        "# INPUTS",
        "",
        "input CreateUserInput {",
        "  username: String!",
        "  email: String!",
        "  password: String!",
        "}",
        "",
        "input AuthUserInput {",
        "  user: String!",
        "  password: String!",
        "  code: String",
        "}",
        "",
        "input RefreshTokensInput{",
        "  refreshToken: String!",
        "}",
        "",
        "input VerifyEmailInput {",
        "  token: String!",
        "}",
        "",
        "# OBJECTS",
        "",
    }

    //Check for boundaries
    inputStart := slices.Index(codeSlices, "# INPUTS") //Use built-in functions for the search
    if inputStart == -1 {
        log.Fatal("# INPUTS not found")
    }

    objectStart := slices.Index(codeSlices, "# OBJECTS")
    if objectStart == -1 {
        log.Fatal("# OBJECTS not found")
    }

    var inputStartSlice []int
    var inputEndSlice []int

    //No need to copy your codeSlices to inputSlice, just go from inputs to objects, this is faster.
    for i := inputStart + 2; i < objectStart-1; i++ {
        if strings.HasSuffix(codeSlices[i], "{") { //HasSuffix is better here, since the { must be the last char
            inputStartSlice = append(inputStartSlice, i)
            continue //No need to check for closing bracket, so we can continue to skip another check
        }
        if codeSlices[i] == "}" { //Direct equality is faster than Contains
            inputEndSlice = append(inputEndSlice, i+1)
        }
    }

    //Check to every open bracket have a closing one
    if len(inputStartSlice) != len(inputEndSlice) {
        log.Fatal("len(inputStartSlice) != len(inputEndSlice)")
    }

    //Concating final results
    var inputs [][]string
    for i := range inputStartSlice {
        inputs = append(inputs, codeSlices[inputStartSlice[i]:inputEndSlice[i]])
    }

    fmt.Println(inputs)
}

你可以在不使用额外变量的情况下实现同样的效果

package main

import (
    "fmt"
    "log"
    "strings"

    "golang.org/x/exp/slices"
)

func main() {

    var codeSlices = []string{
        "# INPUTS",
        "",
        "input CreateUserInput {",
        "  username: String!",
        "  email: String!",
        "  password: String!",
        "}",
        "",
        "input AuthUserInput {",
        "  user: String!",
        "  password: String!",
        "  code: String",
        "}",
        "",
        "input RefreshTokensInput{",
        "  refreshToken: String!",
        "}",
        "",
        "input VerifyEmailInput {",
        "  token: String!",
        "}",
        "",
        "# OBJECTS",
        "",
    }

    //Check for boundaries
    inputStart := slices.Index(codeSlices, "# INPUTS") //Use built-in functions for the search
    if inputStart == -1 {
        log.Fatal("# INPUTS not found")
    }

    objectStart := slices.Index(codeSlices, "# OBJECTS")
    if objectStart == -1 {
        log.Fatal("# OBJECTS not found")
    }

    inputStart = 0
    var inputs [][]string
    for i := inputStart + 2; i < objectStart-1; i++ {
        if idx := strings.Index(codeSlices[i], "{"); idx > 0 {
            inputStart = i
            continue
        }
        if idx := slices.Index(codeSlices[inputStart:], "}"); inputStart > 0 {
            inputs = append(inputs, codeSlices[inputStart:i+idx])
            inputStart = 0
        }
    }

    if inputStart > 0 {
        log.Fatal("Mismatch inputs")
    }

    fmt.Printf("%#v\n", inputs)
}

Playground