Golang slices.DeleteFunc
最后修改于 2025 年 4 月 20 日
本教程将介绍如何在 Go 中使用 slices.DeleteFunc
函数。我们将通过实际删除元素的示例来讲解切片操作。
slices.DeleteFunc
函数会从切片中移除满足给定条件的元素。它是 Go 实验性 slices 包的一部分。
此函数可用于过滤数据或从集合中移除不需要的元素。它会就地修改切片并返回修改后的切片。
基本的 slices.DeleteFunc 示例
slices.DeleteFunc
最简单的用法是移除切片中的所有负数。我们定义一个测试函数来识别要删除的元素。
package main import ( "fmt" "slices" ) func main() { numbers := []int{1, -2, 3, -4, 5} numbers = slices.DeleteFunc(numbers, func(n int) bool { return n < 0 }) fmt.Println("Positive numbers:", numbers) }
我们创建一个包含正数和负数的切片。该函数会移除所有满足条件 (n < 0) 的元素。
删除空字符串
slices.DeleteFunc
可以从切片中过滤掉空字符串。此示例将删除所有空字符串或仅包含空格的字符串。
package main import ( "fmt" "slices" "strings" ) func main() { words := []string{"apple", "", "banana", " ", "cherry"} words = slices.DeleteFunc(words, func(s string) bool { return strings.TrimSpace(s) == "" }) fmt.Println("Non-empty words:", words) }
测试函数使用 strings.TrimSpace
来处理空格。修改后的切片仅包含非空字符串。
使用结构体
我们可以将 slices.DeleteFunc
与自定义结构体类型一起使用。此示例将从切片中移除所有不活跃的用户。
package main import ( "fmt" "slices" ) type User struct { Name string Active bool } func main() { users := []User{ {"Alice", true}, {"Bob", false}, {"Charlie", true}, } users = slices.DeleteFunc(users, func(u User) bool { return !u.Active }) fmt.Println("Active users:", users) }
该函数会检查每个用户的 `Active` 字段。Bob 会被从切片中移除,因为他的 `Active` 状态为 `false`。
删除重复元素
我们可以将 slices.DeleteFunc
与 map 结合使用来删除重复项。此示例仅保留每个唯一数字的第一次出现。
package main import ( "fmt" "slices" ) func main() { numbers := []int{1, 2, 2, 3, 4, 4, 4, 5} seen := make(map[int]bool) numbers = slices.DeleteFunc(numbers, func(n int) bool { if seen[n] { return true } seen[n] = true return false }) fmt.Println("Unique numbers:", numbers) }
map 会跟踪已看到的数字,并删除后续的重复项。结果中每个数字只出现一次。
不区分大小写的字符串过滤
此示例演示了如何使用 slices.DeleteFunc
进行不区分大小写的过滤。我们将移除所有 "apple" 的出现。
package main import ( "fmt" "slices" "strings" ) func main() { fruits := []string{"Apple", "banana", "APPLE", "cherry", "apple"} fruits = slices.DeleteFunc(fruits, func(s string) bool { return strings.EqualFold(s, "apple") }) fmt.Println("Filtered fruits:", fruits) }
strings.EqualFold
执行不区分大小写的比较。所有形式的 "apple" 都将被移除,而不考虑其大小写。
性能注意事项
对于大型切片,测试函数的性能至关重要。本示例将比较不同的过滤方法。
package main import ( "fmt" "slices" "time" ) func main() { largeSlice := make([]int, 1_000_000) for i := range largeSlice { largeSlice[i] = i % 10 // Create repeating pattern } // Simple condition start := time.Now() _ = slices.DeleteFunc(largeSlice, func(n int) bool { return n == 5 }) fmt.Println("Simple condition:", time.Since(start)) // Complex condition start = time.Now() _ = slices.DeleteFunc(largeSlice, func(n int) bool { return n > 5 && n % 2 == 0 }) fmt.Println("Complex condition:", time.Since(start)) }
执行时间取决于条件的复杂性和删除的数量。slices.DeleteFunc
由于就地修改切片而效率很高。
实际示例:输入清理
此实际示例使用 slices.DeleteFunc
清理用户输入,移除无效条目。
package main import ( "fmt" "slices" "strconv" ) func main() { inputs := []string{"42", "invalid", "15", "99", "not_a_number"} // First convert to numbers, tracking valid entries numbers := make([]int, 0, len(inputs)) valid := make([]bool, len(inputs)) for i, s := range inputs { num, err := strconv.Atoi(s) if err == nil { numbers = append(numbers, num) valid[i] = true } } // Now filter the original slice inputs = slices.DeleteFunc(inputs, func(s string) bool { _, err := strconv.Atoi(s) return err != nil }) fmt.Println("Valid numbers:", numbers) fmt.Println("Sanitized inputs:", inputs) }
我们首先识别无效条目,然后使用 slices.DeleteFunc
移除它们。这展示了实际的数据清理过程。
来源
本教程通过各种场景下过滤切片元素的实际示例,介绍了 Go 中的 slices.DeleteFunc
函数。