ArrayReduce 或类似

问题描述 投票:0回答:3

我有一个数组:

const assets = [{
  type: 'X',
  value: 322.12
}, {
  type: 'X',
  value: 413.21
}]

我想要值的总和(735,33)

在node.js中我可以使用:

const sum = assets.reduce((s, val) => ( s = s + val.value), 0)

我如何在 Go 中做同样的事情?

arrays go reduce
3个回答
4
投票

Here 是一个不完整的实现,但它让您了解为什么这是一个坏主意并且不符合 Go 惯用语:

package main

import "fmt"

type Array []int

type ReducerFn func(prev int, next int) int

func (arr Array) Reduce(fn ReducerFn, i int) int {
    prev := i
    for _, v := range arr {
        prev = fn(prev, v)
    }
    return prev
}

func main() {
    i := Array([]int{1,2,4})
    fmt.Println(i.Reduce(func(prev int, next int) int { 
        return prev + next
    }, 10))
}

由于 Go 中没有泛型,因此您必须为每个返回类型创建不同的减速器方法,这可能非常不切实际。

另请参阅 Francesc Campoy 在 dotGo2015 上的演讲,“Functional Go?”


2
投票

我会 Modf()

i = 0
f = 0
for _, asset := range assets {
    integer, frac := Modf(asset.value)
    i += integer
    f += math.Round(frac*100)/100))
}
fmt.Println(i, f)

0
投票

我将此解决方案作为独立功能:

type reducerFn[T any, U any] func(U, T, int) U

func Reduce[T any, U any](slice []T, reducer reducerFn[T, U], initialValue U) U {
    var acc U = initialValue

    for index, item := range slice {
        acc = reducer(acc, item, index)
    }

    return acc
}

因此您可以通过以下方式解决您的问题:

package main

import "fmt"

type reducerFn[T any, U any] func(U, T, int) U

func Reduce[T any, U any](slice []T, reducer reducerFn[T, U], initialValue U) U {
    var acc U = initialValue

    for index, item := range slice {
        acc = reducer(acc, item, index)
    }

    return acc
}

type MyStruct struct {
    Type  string
    Value float64
}

func main() {
    var assets = []MyStruct{
        {
            Type:  "X",
            Value: 322.12,
        }, {
            Type:  "X",
            Value: 413.21,
        },
    }

    result := Reduce(assets, func(acc float64, item MyStruct, _ int) float64 {
        return acc + item.Value
    }, 0.0)

    fmt.Printf("result: %0.2f\n", result)
}

尝试这个游乐场:https://go.dev/play/p/NdfbWWW4uhS

© www.soinside.com 2019 - 2024. All rights reserved.