abcsort

package module
v0.0.0-...-d6ace64 Latest Latest
Warning

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

Go to latest
Published: Mar 30, 2023 License: Apache-2.0 Imports: 4 Imported by: 3

README

abcsort

Build Status Go Reference Go Report Card codecov

Go string sorting library that uses a custom, user-defined alphabet.

Implementation does not convert the input strings into byte or rune slices, so performance is rather good.

Custom sorting can be easiest achieved by using the Sorter helper type, for example:

sorter := abcsort.New("bac")

ss := []string{"abc", "bac", "cba", "CCC"}
sorter.Strings(ss)
fmt.Println(ss)

ss = []string{"abc", "bac", "cba", "CCC"}
sorter.StringsFold(ss)
fmt.Println(ss)

type Person struct {
	Name string
	Age  int
}

ps := []Person{{Name: "alice", Age: 21}, {Name: "bob", Age: 12}}
sorter.Slice(ps, func(i int) string { return ps[i].Name })
fmt.Println(ps)

ps = []Person{{Name: "Alice", Age: 21}, {Name: "Bob", Age: 12}}
sorter.SliceFold(ps, func(i int) string { return ps[i].Name })
fmt.Println(ps)

// Output:
// [CCC bac abc cba]
// [bac abc cba CCC]
// [{bob 12} {alice 21}]
// [{Bob 12} {Alice 21}]

The essence of sorting, the less() function required by the standard lib's sort package is also exposed, and may be used "manually" like this:

weights := Weights("bac")

ss := []string{"abc", "bac", "cba", "CCC"}
sort.Slice(ss, func(i int, j int) bool {
	return Less(ss[i], ss[j], weights)
})
fmt.Println(ss)

// Output:
// [CCC bac abc cba]

Or via the StringSlice type:

weights := Weights("bac")

ss := []string{"abc", "bac", "cba", "CCC"}
strslice := &StringSlice{
	Weights: weights,
	Slice:   ss,
}
sort.Sort(strslice)
fmt.Println(ss)

// Output:
// [CCC bac abc cba]

Documentation

Overview

Package abcsort is a string sorting library that uses a custom, user-defined alphabet.

Implementation does not convert the input strings into byte or rune slices, so performance is rather good.

Custom sorting can be easiest achieved by using the Sorter helper type.

The essence of sorting, the less() function required by the standard lib's sort package is also exposed, and may be used "manually" like this:

weights := Weights("bac")

ss := []string{"abc", "bac", "cba", "CCC"}
sort.Slice(ss, func(i int, j int) bool {
	return Less(ss[i], ss[j], weights)
})
fmt.Println(ss)

// Output:
// [CCC bac abc cba]

Or via the StringSlice type:

weights := Weights("bac")

ss := []string{"abc", "bac", "cba", "CCC"}
strslice := &StringSlice{
	Weights: weights,
	Slice:   ss,
}
sort.Sort(strslice)
fmt.Println(ss)

// Output:
// [CCC bac abc cba]
Example

Example shows how to do custom sorting using the Sorter helper type.

package main

import (
	"fmt"

	"github.com/icza/abcsort"
)

func main() {
	sorter := abcsort.New("bac")

	ss := []string{"abc", "bac", "cba", "CCC"}
	sorter.Strings(ss)
	fmt.Println(ss)

	ss = []string{"abc", "bac", "cba", "CCC"}
	sorter.StringsFold(ss)
	fmt.Println(ss)

	type Person struct {
		Name string
		Age  int
	}

	ps := []Person{{Name: "alice", Age: 21}, {Name: "bob", Age: 12}}
	sorter.Slice(ps, func(i int) string { return ps[i].Name })
	fmt.Println(ps)

	ps = []Person{{Name: "Alice", Age: 21}, {Name: "Bob", Age: 12}}
	sorter.SliceFold(ps, func(i int) string { return ps[i].Name })
	fmt.Println(ps)

}
Output:

[CCC bac abc cba]
[bac abc cba CCC]
[{bob 12} {alice 21}]
[{Bob 12} {Alice 21}]

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Less

func Less(s1, s2 string, weights map[rune]int) bool

Less tells if s1 is less than s2, interpreted as UTF-8 strings, using the given weights (which should be constructed using Weights()).

Example
weights := Weights("bac")

ss := []string{"abc", "bac", "cba", "CCC"}
sort.Slice(ss, func(i int, j int) bool {
	return Less(ss[i], ss[j], weights)
})
fmt.Println(ss)
Output:

[CCC bac abc cba]

func LessFold

func LessFold(s1, s2 string, weights map[rune]int) bool

LessFold tells if s1 is less than s2 under Unicode case folding, interpreted as UTF-8 strings, using the given weights (which should be constructed using WeightsFold()).

func Weights

func Weights(alphabet string) map[rune]int

Weights returns a map containing runes of the given alphabet, position of each rune is used as the weight.

func WeightsFold

func WeightsFold(alphabet string) map[rune]int

WeightsFold returns a map containing lower and upper versions of all runes of the given alphabet, position of each rune is used as the weight.

Types

type Sorter

type Sorter struct {
	// Alphabet is the custom alphabet
	Alphabet string
	// Weights is used for "normal" sorting.
	Weights map[rune]int
	// WeightsFold is used for fold sorting.
	WeightsFold map[rune]int
}

Sorter provides functionality to easily sort slices using a custom alphabet. A sorter is safe for concurrent use.

func New

func New(alphabet string) *Sorter

New returns a new Sorter that will use the given custom alphabet when sorting.

func (*Sorter) Slice

func (s *Sorter) Slice(slice interface{}, getField func(i int) string)

Slice sorts a slice. getField is a function that must return the string value (e.g. a field) of the element at the ith index.

func (*Sorter) SliceFold

func (s *Sorter) SliceFold(slice interface{}, getField func(i int) string)

SliceFold sorts a slice under Unicode folding. getField is a function that must return the string value (e.g. a field) of the element at the ith index.

func (*Sorter) Strings

func (s *Sorter) Strings(ss []string)

Strings sorts a string slice.

func (*Sorter) StringsFold

func (s *Sorter) StringsFold(ss []string)

StringsFold sorts a string slice under Unicode folding.

type StringFoldSlice

type StringFoldSlice struct {
	Slice   []string
	Weights map[rune]int
}

StringFoldSlice is a helper struct that implements sort.Interface.

Example
ss := []string{"bármi", "Áron", "áram"}
sort.Strings(ss)
fmt.Println(ss)

weights := WeightsFold("aábcdeéfghiíjklmnoóöőpqrstuúüűvwxyz")

ss = []string{"bármi", "Áron", "áram"}
strslice := &StringFoldSlice{
	Weights: weights,
	Slice:   ss,
}
sort.Sort(strslice)
fmt.Println(ss)
Output:

[bármi Áron áram]
[áram Áron bármi]

func (*StringFoldSlice) Len

func (ss *StringFoldSlice) Len() int

func (*StringFoldSlice) Less

func (ss *StringFoldSlice) Less(i, j int) bool

func (*StringFoldSlice) Swap

func (ss *StringFoldSlice) Swap(i, j int)

type StringSlice

type StringSlice struct {
	Slice   []string
	Weights map[rune]int
}

StringSlice is a helper struct that implements sort.Interface.

Example
weights := Weights("bac")

ss := []string{"abc", "bac", "cba", "CCC"}
strslice := &StringSlice{
	Weights: weights,
	Slice:   ss,
}
sort.Sort(strslice)
fmt.Println(ss)
Output:

[CCC bac abc cba]

func (*StringSlice) Len

func (ss *StringSlice) Len() int

func (*StringSlice) Less

func (ss *StringSlice) Less(i, j int) bool

func (*StringSlice) Swap

func (ss *StringSlice) Swap(i, j int)

Jump to

Keyboard shortcuts

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