更简洁的方法来遍历数组并从值创建一个字符串

huangapple go评论86阅读模式
英文:

Cleaner way to iterate through array + create a string from values

问题

使用这段代码,有没有更好的方法来遍历所有用户并创建一个包含他们所有Nick值的新字符串?

package main

import "fmt"

type User struct {
    Nick string
}

func main() {
    var users [2]User
    users[0] = User{Nick: "Radar"}
    users[1] = User{Nick: "NotRadar"}
    names := ":"
    for _, u := range users {
        names += u.Nick + " "
    }
    fmt.Println(names)
}
package main

import "fmt"

type User struct {
    Nick string
}

func main() {
    var users [2]User
    users[0] = User{Nick: "Radar"}
    users[1] = User{Nick: "NotRadar"}
    names := ":"
    for _, u := range users {
        names += u.Nick + " "
    }
    fmt.Println(names)
}
英文:

With this code, is there a better way to loop through all the users and create a new string containing all their Nick values?

package main

import "fmt"

type User struct {
	Nick     string
}


func main() {
	var users [2]User
	users[0] = User{ Nick: "Radar" }
	users[1] = User{ Nick: "NotRadar" }
	names := ":"
	for _, u := range users {
		names += u.Nick + " "
	}
	fmt.Println(names)
	
}

答案1

得分: 5

例如,

package main

import (
    "bytes"
    "fmt"
)

type User struct {
    Nick string
}

func main() {
    var users [2]User
    users[0] = User{Nick: "Radar"}
    users[1] = User{Nick: "NotRadar"}
    var buf bytes.Buffer
    buf.WriteByte(':')
    for _, u := range users {
        buf.WriteString(u.Nick)
        buf.WriteByte(' ')
    }
    names := buf.String()
    fmt.Println(names)
}

这样可以避免由于string的连接而产生大量的分配。

你也可以这样写:

package main

import (
    "fmt"
)

type User struct {
    Nick string
}

func main() {
    var users [2]User
    users[0] = User{Nick: "Radar"}
    users[1] = User{Nick: "NotRadar"}
    var buf []byte
    buf = append(buf, ':')
    for _, u := range users {
        buf = append(buf, u.Nick...)
        buf = append(buf, ' ')
    }
    names := string(buf)
    fmt.Println(names)
}
英文:

For example,

package main

import (
	"bytes"
	"fmt"
)

type User struct {
	Nick string
}

func main() {
	var users [2]User
	users[0] = User{Nick: "Radar"}
	users[1] = User{Nick: "NotRadar"}
	var buf bytes.Buffer
	buf.WriteByte(':')
	for _, u := range users {
		buf.WriteString(u.Nick)
		buf.WriteByte(' ')
	}
	names := buf.String()
	fmt.Println(names)
}

This avoids a lot of allocations due to the concatenation of strings.

You could also write:

package main

import (
	"fmt"
)

type User struct {
	Nick string
}

func main() {
	var users [2]User
	users[0] = User{Nick: "Radar"}
	users[1] = User{Nick: "NotRadar"}
	var buf []byte
	buf = append(buf, ':')
	for _, u := range users {
		buf = append(buf, u.Nick...)
		buf = append(buf, ' ')
	}
	names := string(buf)
	fmt.Println(names)
}

答案2

得分: 2

这里看起来你想要使用strings.Join。你可能想要避免原始代码中重复字符串连接的紧密循环;我相当确定Go语言没有为其原始字符串实现类似绳索的数据结构。

package main

import (
	"fmt"
	"strings"
)

type User struct {
	Nick string
}

func main() {
	var users [2]User
	users[0] = User{Nick: "Radar"}
	users[1] = User{Nick: "NotRadar"}
	userNames := []string{}
	for _, u := range users {
		userNames = append(userNames, u.Nick)
	}
	names := ":" + strings.Join(userNames, " ")
	fmt.Println(names)
}
英文:

It really looks like you want a strings.Join here. You probably want to avoid that tight loop of repeated string concatenations in the original code; I'm fairly certain that Go doesn't implement a rope-like data structure for its primitive strings.

package main

import (
	"fmt"
	"strings"
)

type User struct {
	Nick string
}

func main() {
	var users [2]User
	users[0] = User{Nick: "Radar"}
	users[1] = User{Nick: "NotRadar"}
	userNames := []string{}
	for _, u := range users {
		userNames = append(userNames, u.Nick)
	}
	names := ":" + strings.Join(userNames, " ")
	fmt.Println(names)
}

答案3

得分: 1

很不幸,我不知道有更优雅的方法来编写那段代码。

Go确实有一个String.Join方法,所以如果你创建一个将用户数组转换为字符串切片([]string)的辅助函数,然后将其传递给String.Join,就可以实现这个功能。

我认为Go的静态类型和缺乏模板使得编写一个像Ruby那样通用的map函数变得困难。

英文:

Unfortunately, I do not know of a more elegant way to write that code.

Go does have a String.Join method so if you made a helper that converted your array of users to a slice of strings ([]string) then you could pass that to String.Join.

I think that Go's static typing and lack of templates makes it hard to write a general purpose map function like Ruby has.

答案4

得分: 1

这是我在dyoo的帖子评论中谈论的内容。这实际上是对join的重写,以防止额外迭代列表并分配额外的切片。

func Usernames(users []User) string {
    if len(users) == 0 {
        return ""
    }
    if len(users) == 1 {
        return users[0].Name
    }

    sep := " "
    n := len(users)-1 // 从 len(sep) * len(a)-1,sep始终是长度为1,不像Join中那样
    for i := 0; i < len(users); i++ {
        n += len(users[i].Name)
    }

    names := make([]byte,n)
    namesp := copy(names, users[0].Name)
    for _,u := range users[1:] {
        namesp += copy(names[namesp:], sep)
        namesp += copy(names[namesp:], u.Name)
    }
    return string(names)
}

供参考,strings.go中的strings.Join源代码:
http://golang.org/src/pkg/strings/strings.go

请参考第356行。

英文:

This is what I was talking about in the comments of dyoo's post. Effectively a rewrite of join to prevent having to iterate over the list an extra time and allocate an extra slice.

func Usernames(users []User) string {
    if len(users) == 0 {
        return &quot;&quot;
    }
    if len(users) == 1 {
        return users[0].Name
    }

    sep := &quot; &quot;
    n := len(users)-1 // From len(sep) * len(a)-1, sep is always len 1 unlike in Join
    for i := 0; i &lt; len(users); i++ {
        n += len(users[i].Name)
    }

    names := make([]byte,n)
    namesp := copy(names, users[0].Name)
    for _,u := range users[1:] {
        namesp += copy(names[namesp:], sep)
        namesp += copy(names[namesp:], u.Name)
    }
    return string(names)
}

For reference, strings.go with the strings.Join source:
http://golang.org/src/pkg/strings/strings.go

See line 356

huangapple
  • 本文由 发表于 2013年7月31日 07:50:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/17959374.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定