mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-13 05:50:27 +00:00
Separate pathographic sorting code
This commit is contained in:
parent
9f48ded254
commit
0b2e52b99b
@ -3,6 +3,7 @@ package hyphae
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// YieldExistingHyphae iterates over all hyphae and yields all existing ones.
|
// YieldExistingHyphae iterates over all hyphae and yields all existing ones.
|
||||||
@ -33,6 +34,40 @@ func FilterTextHyphae(src chan *Hypha) chan *Hypha {
|
|||||||
return sink
|
return sink
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PathographicSort sorts paths inside the source channel, preserving the path tree structure
|
||||||
|
func PathographicSort(src chan string) <-chan string {
|
||||||
|
out := make(chan string)
|
||||||
|
go func() {
|
||||||
|
// To make it unicode-friendly and lean, we cast every string into rune slices, sort, and only then cast them back
|
||||||
|
raw := make([][]rune, 0)
|
||||||
|
for h := range src {
|
||||||
|
raw = append(raw, []rune(h))
|
||||||
|
}
|
||||||
|
sort.Slice(raw, func(i, j int) bool {
|
||||||
|
const slash rune = 47 // == '/'
|
||||||
|
// Classic lexicographical sort with a twist
|
||||||
|
c := 0
|
||||||
|
for {
|
||||||
|
if c == len(raw[i]) { return true }
|
||||||
|
if c == len(raw[j]) { return false }
|
||||||
|
if raw[i][c] == raw[j][c] {
|
||||||
|
c++
|
||||||
|
} else {
|
||||||
|
// The twist: subhyphae-awareness is about pushing slash upwards
|
||||||
|
if raw[i][c] == slash { return true }
|
||||||
|
if raw[j][c] == slash { return false }
|
||||||
|
return raw[i][c] < raw[j][c]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
for _, name := range raw {
|
||||||
|
out <- string(name)
|
||||||
|
}
|
||||||
|
close(out)
|
||||||
|
}()
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// Subhyphae returns slice of subhyphae.
|
// Subhyphae returns slice of subhyphae.
|
||||||
func (h *Hypha) Subhyphae() []*Hypha {
|
func (h *Hypha) Subhyphae() []*Hypha {
|
||||||
hyphae := []*Hypha{}
|
hyphae := []*Hypha{}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package shroom
|
package shroom
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bouncepaw/mycorrhiza/hyphae"
|
"github.com/bouncepaw/mycorrhiza/hyphae"
|
||||||
@ -11,37 +10,16 @@ import (
|
|||||||
func YieldHyphaNamesContainingString(query string) <-chan string {
|
func YieldHyphaNamesContainingString(query string) <-chan string {
|
||||||
query = util.CanonicalName(query)
|
query = util.CanonicalName(query)
|
||||||
out := make(chan string)
|
out := make(chan string)
|
||||||
|
sorted := hyphae.PathographicSort(out)
|
||||||
go func() {
|
go func() {
|
||||||
// To make it unicode-friendly and lean, we cast every string into rune slices, sort, and only then cast them back
|
|
||||||
raw := make([][]rune, 0)
|
|
||||||
for h := range hyphae.YieldExistingHyphae() {
|
for h := range hyphae.YieldExistingHyphae() {
|
||||||
if hyphaNameMatchesString(h.Name, query) {
|
if hyphaNameMatchesString(h.Name, query) {
|
||||||
raw = append(raw, []rune(h.Name))
|
out <- h.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Slice(raw, func(i, j int) bool {
|
|
||||||
const slash rune = 47 // == '/'
|
|
||||||
// Classic lexicographical sort with a twist
|
|
||||||
c := 0
|
|
||||||
for {
|
|
||||||
if c == len(raw[i]) { return true }
|
|
||||||
if c == len(raw[j]) { return false }
|
|
||||||
if raw[i][c] == raw[j][c] {
|
|
||||||
c++
|
|
||||||
} else {
|
|
||||||
// The twist: subhyphae-awareness is about pushing slash upwards
|
|
||||||
if raw[i][c] == slash { return true }
|
|
||||||
if raw[j][c] == slash { return false }
|
|
||||||
return raw[i][c] < raw[j][c]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
for _, name := range raw {
|
|
||||||
out <- string(name)
|
|
||||||
}
|
|
||||||
close(out)
|
close(out)
|
||||||
}()
|
}()
|
||||||
return out
|
return sorted
|
||||||
}
|
}
|
||||||
|
|
||||||
// This thing gotta be changed one day, when a hero has time to implement a good searching algorithm.
|
// This thing gotta be changed one day, when a hero has time to implement a good searching algorithm.
|
||||||
|
Loading…
Reference in New Issue
Block a user