Short way to apply a function to all elements in a list in golang

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

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 = &#39;, &#39;.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, &quot;, &quot;)

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 (
    &quot;fmt&quot;
    &quot;strconv&quot;
    &quot;strings&quot;
)

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, &quot;, &quot;)
    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

我已经创建了一个小的实用程序包,其中包含了MapFilter方法,现在在1.18版本中引入了泛型 Short way to apply a function to all elements in a list in golang

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 Mapand Filter methods now that generics have been introduced in 1.18 Short way to apply a function to all elements in a list in golang

https://pkg.go.dev/github.com/sa-/slicefunk

Example usage

package main

import (
	&quot;fmt&quot;

	sf &quot;github.com/sa-/slicefunk&quot;
)

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(&quot;Item:%d&quot;, 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 &lt; 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, &quot;,&quot;)

huangapple
  • 本文由 发表于 2015年11月16日 08:14:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/33726731.html
匿名

发表评论

匿名网友

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

确定