Golang slices.CompactFunc Function

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

  1. Introduction
  2. slices.CompactFunc Function Syntax
  3. Examples
    • Basic Usage
    • Compacting a Slice of Structs
    • Handling Complex Equality Conditions
  4. Real-World Use Case Example
  5. 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.CompactFunc function 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.CompactFunc function removes consecutive duplicate Person structs based on both Name and Age, 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.CompactFunc function removes consecutive duplicate Product structs based on Name and Price only, ignoring the ID field, 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.CompactFunc function removes consecutive duplicate UserAction entries based on the UserID, Action, and Resource fields, 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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top