ZetCode

Golang maps.DeleteFunc

最后修改于 2025 年 4 月 20 日

本教程将介绍如何在 Go 中使用 maps.DeleteFunc 函数。我们将通过条件删除的实际示例来讲解 map 操作。

maps.DeleteFunc 函数从 map 中移除满足给定条件的键值对。它是 Go 实验性 maps 包的一部分。

此函数可用于基于复杂条件选择性地删除元素。它会就地修改 map,并且不返回新的 map。

基本的 maps.DeleteFunc 示例

maps.DeleteFunc 最简单的用法是删除所有值为负数的条目。我们为删除条件定义了一个测试函数。

basic_delete.go
package main

import (
    "fmt"
    "maps"
)

func main() {
    m := map[string]int{
        "a": 1,
        "b": -2,
        "c": 3,
        "d": -4,
    }
    
    maps.DeleteFunc(m, func(k string, v int) bool {
        return v < 0
    })
    
    fmt.Println("Map after deletion:", m)
}

我们创建一个包含一些负值的 map 并将它们删除。匿名函数根据值定义了我们的删除条件。

基于键的删除

maps.DeleteFunc 可以使用键信息来决定删除。此示例删除键以“b”开头的条目。

key_based_delete.go
package main

import (
    "fmt"
    "maps"
    "strings"
)

func main() {
    m := map[string]int{
        "apple":  5,
        "banana": 3,
        "berry":  7,
        "orange": 2,
    }
    
    maps.DeleteFunc(m, func(k string, v int) bool {
        return strings.HasPrefix(k, "b")
    })
    
    fmt.Println("Map after deletion:", m)
}

测试函数会检查每个键的开头。所有键以“b”开头的条目都将从 map 中删除。

使用结构体值

我们可以将 maps.DeleteFunc 与包含结构体值的 map 一起使用。此示例删除不活跃的用户。

struct_values_delete.go
package main

import (
    "fmt"
    "maps"
)

type User struct {
    Name   string
    Active bool
}

func main() {
    users := map[int]User{
        1: {"Alice", true},
        2: {"Bob", false},
        3: {"Charlie", true},
    }
    
    maps.DeleteFunc(users, func(k int, v User) bool {
        return !v.Active
    })
    
    fmt.Println("Active users:", users)
}

该函数会检查每个用户的 Active 字段。不活跃的用户将从 map 中删除,而活跃的用户将保留。

合并键和值条件

复杂条件可以结合键和值的检查。此示例删除库存不足且 ID 特定的产品。

combined_conditions_delete.go
package main

import (
    "fmt"
    "maps"
)

func main() {
    inventory := map[int]int{
        101: 5,
        102: 0,
        103: 10,
        201: 2,
        202: 7,
    }
    
    maps.DeleteFunc(inventory, func(id int, stock int) bool {
        return stock < 3 || id >= 200
    })
    
    fmt.Println("Filtered inventory:", inventory)
}

该条件结合了库存水平和产品 ID 检查。库存不足或 ID ≥ 200 的产品将被删除。

空映射行为

maps.DeleteFunc 可以优雅地处理空 map。此示例演示了其在空 map 上的行为。

empty_map_delete.go
package main

import (
    "fmt"
    "maps"
)

func main() {
    m := map[string]int{}
    
    maps.DeleteFunc(m, func(k string, v int) bool {
        return true // Would delete all if any existed
    })
    
    fmt.Println("Empty map remains:", m)
}

由于没有要处理的元素,该函数什么也不做。操作后 map 仍然是空的。

性能注意事项

对于大型 map,测试函数的性能很重要。此示例对不同的删除条件进行了基准测试。

performance_delete.go
package main

import (
    "fmt"
    "maps"
    "time"
)

func main() {
    largeMap := make(map[int]int, 1_000_000)
    for i := 0; i < 1_000_000; i++ {
        largeMap[i] = i
    }
    
    // Simple condition
    start := time.Now()
    maps.DeleteFunc(largeMap, func(k, v int) bool {
        return v%2 == 0
    })
    fmt.Println("Simple condition:", time.Since(start))
    
    // Reset map
    largeMap = make(map[int]int, 1_000_000)
    for i := 0; i < 1_000_000; i++ {
        largeMap[i] = i
    }
    
    // Complex condition
    start = time.Now()
    maps.DeleteFunc(largeMap, func(k, v int) bool {
        return v%2 == 0 && k > 500_000 && v < 750_000
    })
    fmt.Println("Complex condition:", time.Since(start))
}

执行时间取决于条件的复杂性和删除的数量。maps.DeleteFunc 顺序处理每个元素。

实际示例:缓存清理

这个实际示例演示了如何通过删除过期的条目来使用 maps.DeleteFunc 进行缓存清理。

cache_cleanup.go
package main

import (
    "fmt"
    "maps"
    "time"
)

type CacheEntry struct {
    Value    string
    ExpireAt time.Time
}

func main() {
    cache := map[string]CacheEntry{
        "user:1": {"Alice", time.Now().Add(5 * time.Minute)},
        "user:2": {"Bob", time.Now().Add(-1 * time.Hour)},
        "user:3": {"Charlie", time.Now().Add(10 * time.Minute)},
    }
    
    maps.DeleteFunc(cache, func(k string, v CacheEntry) bool {
        return time.Now().After(v.ExpireAt)
    })
    
    fmt.Println("Active cache entries:")
    for k, v := range cache {
        fmt.Printf("%s: %s\n", k, v.Value)
    }
}

我们会将每个缓存条目的过期时间与当前时间进行比较。过期的条目将被删除,而有效的条目将保留在缓存中。

来源

Go 实验性 maps 包文档

本教程通过各种场景下条件性删除 map 元素的实际示例,介绍了 Go 中的 maps.DeleteFunc 函数。

作者

我叫 Jan Bodnar,是一名热情的程序员,拥有丰富的编程经验。我自 2007 年起就开始撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Go 教程