The slices.CompactFunc function in Golang is part of the slices package, introduced in Go 1.21 as part of the standard library. This function is designed to remove consecutive duplicate elements from a slice based on a custom equality function provided by the user. It returns a new slice with only unique elements in their original order according to the equality function.
Table of Contents
- Introduction
slices.CompactFuncFunction Syntax- Examples
- Basic Usage
- Compacting a Slice of Structs
- Handling Complex Equality Conditions
- Real-World Use Case Example
- Conclusion
Introduction
The slices.CompactFunc function is useful when you need to remove consecutive duplicate elements from a slice but with custom logic for determining equality. Unlike slices.Compact, which relies on the default equality operator, slices.CompactFunc allows you to define your own comparison function, making it more flexible for complex types and specific conditions.
slices.CompactFunc Function Syntax
The syntax for the slices.CompactFunc function is as follows:
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S
Parameters:
s S: The slice you want to compact.eq func(E, E) bool: The custom function that determines whether two elements are equal.
Returns:
S: A new slice with consecutive duplicate elements removed according to the custom equality function.
Behavior:
- Removes consecutive duplicates: The function returns a slice with only unique consecutive elements from the original slice, based on the custom equality function.
Examples
Basic Usage
This example demonstrates how to use slices.CompactFunc to remove consecutive duplicate integers from a slice using a custom equality function.
Example
package main
import (
"fmt"
"slices"
)
func main() {
// Original slice with consecutive duplicates
slice := []int{1, 1, 2, 2, 3, 3, 3, 4, 4}
// Custom equality function to compare integers
eq := func(a, b int) bool {
return a == b
}
// Use slices.CompactFunc to remove consecutive duplicates
compactSlice := slices.CompactFunc(slice, eq)
// Print the compacted slice
fmt.Println("Compacted slice:", compactSlice)
}
Output:
Compacted slice: [1 2 3 4]
Explanation:
- The
slices.CompactFuncfunction uses the custom equality function to remove consecutive duplicates from the slice, resulting in[1, 2, 3, 4].
Compacting a Slice of Structs
This example demonstrates how to use slices.CompactFunc to compact a slice of structs based on a custom equality condition.
Example
package main
import (
"fmt"
"slices"
)
type Person struct {
Name string
Age int
}
func main() {
// Original slice with consecutive duplicate structs
people := []Person{
{Name: "Alice", Age: 30},
{Name: "Alice", Age: 30},
{Name: "Bob", Age: 25},
{Name: "Bob", Age: 25},
{Name: "Charlie", Age: 35},
}
// Custom equality function to compare Person structs
eq := func(a, b Person) bool {
return a.Name == b.Name && a.Age == b.Age
}
// Use slices.CompactFunc to remove consecutive duplicates
compactPeople := slices.CompactFunc(people, eq)
// Print the compacted slice
fmt.Println("Compacted people:", compactPeople)
}
Output:
Compacted people: [{Alice 30} {Bob 25} {Charlie 35}]
Explanation:
- The
slices.CompactFuncfunction removes consecutive duplicatePersonstructs based on bothNameandAge, resulting in a slice with unique consecutive elements.
Handling Complex Equality Conditions
This example demonstrates how slices.CompactFunc can be used to compact a slice with complex equality conditions, such as ignoring certain fields in the comparison.
Example
package main
import (
"fmt"
"slices"
)
type Product struct {
Name string
Price float64
ID int
}
func main() {
// Original slice with consecutive duplicate products
products := []Product{
{Name: "Laptop", Price: 1000, ID: 1},
{Name: "Laptop", Price: 1000, ID: 2},
{Name: "Phone", Price: 500, ID: 3},
{Name: "Phone", Price: 500, ID: 4},
}
// Custom equality function to compare Products based on Name and Price only
eq := func(a, b Product) bool {
return a.Name == b.Name && a.Price == b.Price
}
// Use slices.CompactFunc to remove consecutive duplicates
compactProducts := slices.CompactFunc(products, eq)
// Print the compacted slice
fmt.Println("Compacted products:", compactProducts)
}
Output:
Compacted products: [{Laptop 1000 1} {Phone 500 3}]
Explanation:
- The
slices.CompactFuncfunction removes consecutive duplicateProductstructs based onNameandPriceonly, ignoring theIDfield, resulting in a compacted slice.
Real-World Use Case Example: Deduplicating User Actions
A practical use case for slices.CompactFunc is deduplicating user actions in a log where consecutive identical actions should be collapsed into one.
Example: Compacting User Actions Log
package main
import (
"fmt"
"slices"
)
type UserAction struct {
UserID int
Action string
Resource string
}
func main() {
// Simulated log of user actions with consecutive duplicates
actions := []UserAction{
{UserID: 1, Action: "view", Resource: "homepage"},
{UserID: 1, Action: "view", Resource: "homepage"},
{UserID: 1, Action: "click", Resource: "button"},
{UserID: 2, Action: "view", Resource: "homepage"},
{UserID: 2, Action: "view", Resource: "homepage"},
}
// Custom equality function to compare UserActions
eq := func(a, b UserAction) bool {
return a.UserID == b.UserID && a.Action == b.Action && a.Resource == b.Resource
}
// Use slices.CompactFunc to remove consecutive duplicate actions
compactActions := slices.CompactFunc(actions, eq)
// Print the compacted user actions
fmt.Println("Compacted user actions:", compactActions)
}
Output:
Compacted user actions: [{1 view homepage} {1 click button} {2 view homepage}]
Explanation:
- The
slices.CompactFuncfunction removes consecutive duplicateUserActionentries based on theUserID,Action, andResourcefields, making the log more concise.
Conclusion
The slices.CompactFunc function in Go is used for removing consecutive duplicate elements from slices using custom equality logic. It is particularly useful in scenarios where you need to apply specific conditions for equality, such as ignoring certain fields or comparing complex types. By using slices.CompactFunc, you can effectively clean up and simplify your slices, making them more efficient and easier to work with in your Go applications.