英文:
Short way to apply a function to all elements in a list in golang
问题
假设我想对列表中的每个元素应用一个函数,然后将结果值放入另一个列表中,以便我可以立即使用它们。在Python中,我会这样做:
list = [1,2,3]
str = ', '.join(multiply(x, 2) for x in list)
在Go中,我会这样做:
list := []int{1,2,3}
list2 := []int
for _,x := range list {
list2 := append(list2, multiply(x, 2))
}
str := strings.Join(list2, ", ")
有没有更简洁的方法来实现这个功能?
英文:
Suppose I would like to apply a function to every element in a list, and then put the resulting values in another list so I can immediately use them. In python, I would do something like this:
<!-- language: python -->
list = [1,2,3]
str = ', '.join(multiply(x, 2) for x in list)
<!-- language: go -->
In Go, I do something like this:
list := []int{1,2,3}
list2 := []int
for _,x := range list {
list2 := append(list2, multiply(x, 2))
}
str := strings.Join(list2, ", ")
Is it possible to do this in a shorter way?
答案1
得分: 21
我会按照你的做法进行,只是稍作修改来修复拼写错误。
import (
"fmt"
"strconv"
"strings"
)
func main() {
list := []int{1,2,3}
var list2 []string
for _, x := range list {
list2 = append(list2, strconv.Itoa(x * 2)) // 注意使用 = 而不是 :=
}
str := strings.Join(list2, ", ")
fmt.Println(str)
}
以上是翻译好的代码部分。
英文:
I would do exactly as you did, with a few tweaks to fix typos
import (
"fmt"
"strconv"
"strings"
)
func main() {
list := []int{1,2,3}
var list2 []string
for _, x := range list {
list2 = append(list2, strconv.Itoa(x * 2)) // note the = instead of :=
}
str := strings.Join(list2, ", ")
fmt.Println(str)
}
答案2
得分: 19
这是一个旧问题,但在我的谷歌搜索中排名靠前,我找到了一些信息,我相信对于提问者和其他寻找相同答案的人会有帮助。
有一种更简短的方法,尽管你需要自己编写map函数。
在Go语言中,func
是一种类型,它允许你编写一个函数,该函数接受主题切片和一个函数作为输入,并在该切片上进行迭代,应用该函数。
请参考Go by Example页面底部的Map
函数:https://gobyexample.com/collection-functions
我在这里引用了它供参考:
func Map(vs []string, f func(string) string) []string {
vsm := make([]string, len(vs))
for i, v := range vs {
vsm[i] = f(v)
}
return vsm
}
然后你可以这样调用它:
fmt.Println(Map(strs, strings.ToUpper))
所以,是的:你正在寻找的更简短的方法是存在的,尽管它不是内置在语言本身中的。
英文:
This is an old question, but was the top hit in my Google search, and I found information that I believe will be helpful to the OP and anyone else who arrives here, looking for the same thing.
There is a shorter way, although you have to write the map function yourself.
In go, func
is a type, which allows you to write a function that accepts as input the subject slice and a function, and which iterates over that slice, applying that function.
See the Map
function near the bottom of this Go by Example page : https://gobyexample.com/collection-functions
I've included it here for reference:
func Map(vs []string, f func(string) string) []string {
vsm := make([]string, len(vs))
for i, v := range vs {
vsm[i] = f(v)
}
return vsm
}
You then call it like so:
fmt.Println(Map(strs, strings.ToUpper))
So, yes: The shorter way you are looking for exists, although it is not built into the language itself.
答案3
得分: 14
我已经创建了一个小的实用程序包,其中包含了Map
和Filter
方法,现在在1.18版本中引入了泛型
https://pkg.go.dev/github.com/sa-/slicefunk
示例用法
package main
import (
"fmt"
sf "github.com/sa-/slicefunk"
)
func main() {
original := []int{1, 2, 3, 4, 5}
newArray := sf.Map(original, func(item int) int { return item + 1 })
newArray = sf.Map(newArray, func(item int) int { return item * 3 })
newArray = sf.Filter(newArray, func(item int) bool { return item%2 == 0 })
fmt.Println(newArray)
}
英文:
I've created a small utility package with Map
and Filter
methods now that generics have been introduced in 1.18
https://pkg.go.dev/github.com/sa-/slicefunk
Example usage
package main
import (
"fmt"
sf "github.com/sa-/slicefunk"
)
func main() {
original := []int{1, 2, 3, 4, 5}
newArray := sf.Map(original, func(item int) int { return item + 1 })
newArray = sf.Map(newArray, func(item int) int { return item * 3 })
newArray = sf.Filter(newArray, func(item int) bool { return item%2 == 0 })
fmt.Println(newArray)
}
答案4
得分: 10
使用go1.18+,您可以编写一个更简洁的通用Map函数:
func Map[T, V any](ts []T, fn func(T) V) []V {
result := make([]V, len(ts))
for i, t := range ts {
result[i] = fn(t)
}
return result
}
用法示例:
input := []int{4, 5, 3}
outputInts := Map(input, func(item int) int { return item + 1 })
outputStrings := Map(input, func(item int) string { return fmt.Sprintf("Item:%d", item) })
英文:
With go1.18+ you can write a much cleaner generic Map function:
func Map[T, V any](ts []T, fn func(T) V) []V {
result := make([]V, len(ts))
for i, t := range ts {
result[i] = fn(t)
}
return result
}
Usage, e.g:
input := []int{4, 5, 3}
outputInts := Map(input, func(item int) int { return item + 1 })
outputStrings := Map(input, func(item int) string { return fmt.Sprintf("Item:%d", item) })
答案5
得分: 5
找到了一种定义通用映射数组函数的方法
func Map(t interface{}, f func(interface{}) interface{}) []interface{} {
switch reflect.TypeOf(t).Kind() {
case reflect.Slice:
s := reflect.ValueOf(t)
arr := make([]interface{}, s.Len())
for i := 0; i < s.Len(); i++ {
arr[i] = f(s.Index(i).Interface())
}
return arr
}
return nil
}
origin := []int{4,5,3}
newArray := Map(origin, func(item interface{}) interface{} { return item.(int) + 1})
英文:
Found a way to define a generic map array function
func Map(t interface{}, f func(interface{}) interface{} ) []interface{} {
switch reflect.TypeOf(t).Kind() {
case reflect.Slice:
s := reflect.ValueOf(t)
arr := make([]interface{}, s.Len())
for i := 0; i < s.Len(); i++ {
arr[i] = f(s.Index(i).Interface())
}
return arr
}
return nil
}
origin := []int{4,5,3}
newArray := Map(origin, func(item interface{}) interface{} { return item.(int) + 1})
答案6
得分: 2
你可以使用lo的Map函数来快速将一个函数应用到所有元素上。例如,要将每个元素乘以2并转换为字符串,你可以使用以下代码:
l := lo.Map[int, string]([]int{1, 2, 3, 4}, func(x int, _ int) string { return strconv.Itoa(x * 2) })
然后你可以将结果转换回以逗号分隔的字符串,像这样:
strings.Join(l, ",")
英文:
You can use lo's Map in order to quickly apply a function to all elements. For example, in order to multiply by 2 and convert to string, you can use:
l := lo.Map[int, string]([]int{1, 2, 3, 4}, func(x int, _ int) string { return strconv.Itoa(x * 2) })
Then you can convert back to a comma delimited string like so:
strings.Join(l, ",")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论