ZetCode

Golang slices.MinFunc

最后修改于 2025 年 4 月 20 日

本教程将解释如何在 Go 中使用 slices.MinFunc 函数。我们将介绍如何使用自定义比较函数查找最小元素。

slices.MinFunc 函数根据自定义比较函数返回切片中的最小元素。它是 Go 实验性 slices 包的一部分。

当您需要根据自定义排序规则或复杂数据类型查找最小值时,此函数非常有用。它返回找到的第一个最小值。

基本的 slices.MinFunc 示例

slices.MinFunc 最简单的用法是查找切片中最小的数字。我们定义一个返回 -1、0 或 1 的比较函数。

basic_min.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    numbers := []int{3, 1, 4, 1, 5, 9}
    
    min := slices.MinFunc(numbers, func(a, b int) int {
        if a < b {
            return -1
        } else if a > b {
            return 1
        }
        return 0
    })
    
    fmt.Println("Minimum number:", min)
}

我们创建一个数字切片并使用标准比较查找最小值。该函数为切片中的最小元素返回 1。

查找最小字符串长度

slices.MinFunc 可以查找长度最小的字符串。此示例通过字符串长度而不是字典顺序进行比较。

string_min.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    words := []string{"apple", "banana", "cherry", "date"}
    
    shortest := slices.MinFunc(words, func(a, b string) int {
        if len(a) < len(b) {
            return -1
        } else if len(a) > len(b) {
            return 1
        }
        return 0
    })
    
    fmt.Println("Shortest word:", shortest)
}

比较函数检查字符串长度而不是其内容。返回“Date”作为最短字符串,长度为 4 个字符。

使用结构体

我们可以将 slices.MinFunc 与自定义结构体类型一起使用。此示例查找切片中最年轻的人。

struct_min.go
package main

import (
    "fmt"
    "slices"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    people := []Person{
        {"Alice", 25},
        {"Bob", 30},
        {"Charlie", 17},
    }
    
    youngest := slices.MinFunc(people, func(a, b Person) int {
        if a.Age < b.Age {
            return -1
        } else if a.Age > b.Age {
            return 1
        }
        return 0
    })
    
    fmt.Println("Youngest person:", youngest.Name)
}

该函数比较每个 Person 结构体的 Age 字段。Charlie 以 17 岁被返回为最年轻的人。

不区分大小写的字符串比较

此示例演示了在比较中忽略大小写差异的同时查找最小字符串。

case_insensitive.go
package main

import (
    "fmt"
    "slices"
    "strings"
)

func main() {
    words := []string{"Apple", "banana", "cherry", "aardvark"}
    
    min := slices.MinFunc(words, func(a, b string) int {
        aLower := strings.ToLower(a)
        bLower := strings.ToLower(b)
        if aLower < bLower {
            return -1
        } else if aLower > bLower {
            return 1
        }
        return 0
    })
    
    fmt.Println("First in alphabetical order:", min)
}

比较在比较之前将字符串转换为小写。尽管有原始大小写,“aardvark”仍被返回为最小值。

空切片行为

使用空切片调用 slices.MinFunc 时会引发 panic。此示例演示了正确的错误处理。

empty_slice.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    var empty []int
    
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()
    
    // This will panic
    _ = slices.MinFunc(empty, func(a, b int) int {
        if a < b {
            return -1
        } else if a > b {
            return 1
        }
        return 0
    })
}

函数会 panic,因为空切片中没有有效的最小值。在生产代码中调用 MinFunc 之前,请务必检查切片长度。

按绝对值查找最小值

此示例查找绝对值最小的数字,展示了自定义数学比较。

absolute_min.go
package main

import (
    "fmt"
    "math"
    "slices"
)

func main() {
    numbers := []int{-5, 2, -1, 3, -2}
    
    minAbs := slices.MinFunc(numbers, func(a, b int) int {
        absA := math.Abs(float64(a))
        absB := math.Abs(float64(b))
        if absA < absB {
            return -1
        } else if absA > absB {
            return 1
        }
        return 0
    })
    
    fmt.Println("Number with smallest absolute value:", minAbs)
}

比较函数使用绝对值而不是数字本身。-1 被返回为具有最小绝对值(1)。

实际示例:查找最便宜的产品

这个实际示例使用 slices.MinFunc 和自定义比较来查找切片中最便宜的产品。

cheapest_product.go
package main

import (
    "fmt"
    "slices"
)

type Product struct {
    Name  string
    Price float64
}

func main() {
    products := []Product{
        {"Laptop", 999.99},
        {"Phone", 699.99},
        {"Tablet", 299.99},
        {"Monitor", 199.99},
    }
    
    cheapest := slices.MinFunc(products, func(a, b Product) int {
        if a.Price < b.Price {
            return -1
        } else if a.Price > b.Price {
            return 1
        }
        return 0
    })
    
    fmt.Printf("Cheapest product: %s ($%.2f)\n", cheapest.Name, cheapest.Price)
}

我们按 Price 字段比较 Product 结构体。Monitor 以 $199.99 的价格被返回为最便宜的产品。

来源

Go 实验性切片包文档

本教程介绍了 Go 中的 slices.MinFunc 函数,并通过使用自定义比较函数查找最小元素的实际示例进行了说明。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Go 教程