【问题标题】:Convert []int to []string in golang in one linegolang 中的 []int 转换为 []string 一行
【发布时间】:2018-12-10 01:04:47
【问题描述】:

我是 Go 的初学者。用几行代码将一个整数切片转换为一个字符串切片看起来很简单:

nums := []int{1, 2, 3, 4}
sNums := make([]string, len(nums))
for i, x := range nums {
    sNums[i] = strconv.Itoa(x)
}

但是,我想知道是否有一种方法可以使用内置/标准库的快速单线器来实现,类似于 Python 中的以下内容:

sNums = map(str, nums)

【问题讨论】:

  • 这是使用标准库中可用函数的最短代码。
  • Go 不喜欢“快速单行”。 Go 采用从不隐藏复杂性的方法,因此明确的 for 循环是 Go 中的正确方法。
  • 您可以将该代码包装在一个 func 中,然后将其作为单线调用。函数在 Go 中很便宜

标签: string go slice


【解决方案1】:

您似乎正在寻找对切片进行操作的map 函数。这将需要泛型,从 Go 1.11 开始,尚不支持泛型。标准库也没有为这些类型的操作(map、filter、reduce 等)提供内置函数。

对于这个简单的用例,您已经拥有的已经足够了。将它包装在一个函数中,这将满足您的需要。在 Go 支持泛型之前,您必须对每种类型的切片手动编写操作。

一些阅读链接:

Generics Proposal

Rob Pike's Filter Library

【讨论】:

    【解决方案2】:

    你想要的可以用一行来完成,但这些解决方案(在性能上)不如你在问题中提出的简单循环。所以这里有一些单行,但我可能永远不会使用它们来实现你想要的,所以只需使用 for 循环,如果你必须多次这样做,创建一个辅助函数(将使用循环),然后调用辅助函数。

    以下单行代码都建立在fmt.Sprint() 函数之上,该函数为int 切片生成字符串表示形式,如下所示(不带引号):

    "[e1 e2 e3...]"
    

    其中e1e2...是输入切片的元素。

    例如:

    nums := []int{1, 2, -3, 4}
    s := fmt.Sprint(nums)
    fmt.Printf("%q", s)
    

    将输出(在Go Playground 上尝试):

    "[1 2 -3 4]"
    

    我们可以使用 2 个步骤将这个单一的 string 值“转换”为它的元素:

    1. 去掉开头和结尾的方括号
    2. 在空格上拆分(打断)剩余文本

    我们完成了。

    第一步,我们有几个选择,例如strings.Replace()strings.Replacerstrings.Trim()。我们可以通过对字符串进行切片来“增加”修剪的趣味性,以剪切它的第一个字符(例如s[1:]),这样就只需要删除尾随的']'

    第二步,我们有strings.Split()

    如果没有所有可能的组合,这里有 3 个单行示例,用于将 int 切片转换为 string 切片:

    nums := []int{1, 2, -3, 4}
    
    sNums := strings.Split(strings.Replace(fmt.Sprint(nums)[1:], "]", "", -1), " ")
    fmt.Printf("%q\n", sNums)
    
    sNums2 := strings.Split(strings.Trim(fmt.Sprint(nums), "[]"), " ")
    fmt.Printf("%q\n", sNums2)
    
    sNums3 := strings.Split(strings.TrimRight(fmt.Sprint(nums)[1:], "]"), " ")
    fmt.Printf("%q\n", sNums3)
    

    上面的输出(在Go Playground上试试):

    ["1" "2" "-3" "4"]
    ["1" "2" "-3" "4"]
    ["1" "2" "-3" "4"]
    

    上述解决方案都不能处理一种极端情况:如果输入是一个空切片,则输出将是一个包含空字符串的切片(当它应该是一个空切片时)。这样做的原因是,如果输入不包含空格分隔符(在本例中为空字符串),strings.Split() 将返回输入(将是空字符串)。

    为了处理空输入切片边缘情况,我们可以使用strings.SplitN() 函数而不是strings.Split(),传递len(nums) 作为我们想要的最大零件数。所以如果输入切片为空,输出切片也将为空:

    nums := []int{}
    
    sNums := strings.SplitN(strings.Replace(fmt.Sprint(nums)[1:], "]", "", -1), " ", len(nums))
    fmt.Printf("%q\n", sNums)
    
    sNums2 := strings.SplitN(strings.Trim(fmt.Sprint(nums), "[]"), " ", len(nums))
    fmt.Printf("%q\n", sNums2)
    
    sNums3 := strings.SplitN(strings.TrimRight(fmt.Sprint(nums)[1:], "]"), " ", len(nums))
    fmt.Printf("%q\n", sNums3)
    

    这将正确输出(在Go Playground 上尝试):

    []
    []
    []
    

    这里需要注意一点:所呈现的解决方案有点像通用的,因为这些解决方案适用于其他类型的切片,例如[]int8[]int32[]float32 等,即使是数组,例如[4]int...

    【讨论】:

      猜你喜欢
      • 2017-02-09
      • 1970-01-01
      • 1970-01-01
      • 2015-08-30
      • 2017-10-17
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      相关资源
      最近更新 更多