deepunique

package module
v0.0.0-...-3f3d5d1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 9, 2025 License: MIT Imports: 5 Imported by: 0

README

DeepUnique

Package deepunique is a Go package expanding the unique package to support the semantics of the reflect.DeepEqual function, including adding support for noncomparable types like slices and maps.

This is primarily useful for efficiently filtering slices so that none of the elements are DeepEqual to each other.

This is similar to making a "set", but with more useful semantics. For example, deepunique will treat two different pointers to the same value as equal.

Example

alice := "Alice"
otherAlice := "Alice"

alices := []*string{&alice, &otherAlice}

// This will filter out one of the alices.
uniqueAlices := deepunique.Unique(alices)

See example_test.go for how this compares to reflect.DeepEqual and unique.Make.

Advanced Usage

The unique handles can be used directly, but there's some complexity around maintaining the internal unique pointers through the serialization needed to support slices. See example_test.go.

Limitations

This package does not currently support recursive types and may encounter issues with Chan, UnsafePointer, or Invalid types.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeduplicatePointerless

func DeduplicatePointerless[T comparable](items []T) []T

func Make

func Make[T any](value T) (unique.Handle[string], any, error)
Example
alice := "Alice"
deepHandle, deepPointers, err := Make(&alice)
if err != nil {
	fmt.Println("Error:", err)
	return
}

otherAlice := "Alice"
otherDeepHandle, otherDeepPointers, err := Make(&otherAlice)
if err != nil {
	fmt.Println("Error:", err)
	return
}

// Avoid "unused variable" errors. I hope this preserves the pointers through
// garbage collection.
_ = deepPointers
_ = otherDeepPointers

fmt.Println("alice and otherAlice have the same deep handle:", deepHandle == otherDeepHandle)
Output:

alice and otherAlice have the same deep handle: true

func SlowUnique

func SlowUnique[T any](items []T) []T

func SortMapTuples

func SortMapTuples(items [][2]any, index []string)

func Unique

func Unique[T any](items []T) ([]T, error)
Example
alice := "Alice"
otherAlice := "Alice"

alices := []*string{&alice, &otherAlice}
if !reflect.DeepEqual(&alice, &otherAlice) {
	fmt.Println("Expected alice and otherAlice to be deep equal")
}

if unique.Make(&alice) == unique.Make(&otherAlice) {
	fmt.Println("Expected alice and otherAlice to have different unique handles")
}

uniqueAlices, err := Unique(alices)
if err != nil {
	fmt.Println("Error:", err)
	return
}

fmt.Println("Length of uniqueAlices:", len(uniqueAlices))
Output:

Length of uniqueAlices: 1

func UniquePointerless

func UniquePointerless[T comparable](items []T) []T

Types

type SerializableHandle

type SerializableHandle[T comparable] struct {
	Value string // stringified unique.Handle
	// contains filtered or unexported fields
}

func NewSerializableHandle

func NewSerializableHandle[T comparable](value T) SerializableHandle[T]

type TypedAny

type TypedAny struct {
	Type  SerializableHandle[reflect.Type]
	Value any
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL