mirror of
https://github.com/sjwhitworth/golearn.git
synced 2025-04-26 13:49:14 +08:00
149 lines
3.6 KiB
Go
149 lines
3.6 KiB
Go
package base
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// This file contains utility functions relating to Attributes and Attribute specifications.
|
|
|
|
// NonClassFloatAttributes returns all FloatAttributes which
|
|
// aren't designated as a class Attribute.
|
|
func NonClassFloatAttributes(d DataGrid) []Attribute {
|
|
classAttrs := d.AllClassAttributes()
|
|
allAttrs := d.AllAttributes()
|
|
ret := make([]Attribute, 0)
|
|
for _, a := range allAttrs {
|
|
matched := false
|
|
if _, ok := a.(*FloatAttribute); !ok {
|
|
continue
|
|
}
|
|
for _, b := range classAttrs {
|
|
if a.Equals(b) {
|
|
matched = true
|
|
break
|
|
}
|
|
}
|
|
if !matched {
|
|
ret = append(ret, a)
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// NonClassAttrs returns all Attributes which aren't designated as a
|
|
// class Attribute.
|
|
func NonClassAttributes(d DataGrid) []Attribute {
|
|
classAttrs := d.AllClassAttributes()
|
|
allAttrs := d.AllAttributes()
|
|
return AttributeDifferenceReferences(allAttrs, classAttrs)
|
|
}
|
|
|
|
// ResolveAttributes returns AttributeSpecs describing
|
|
// all of the Attributes.
|
|
func ResolveAttributes(d DataGrid, attrs []Attribute) []AttributeSpec {
|
|
ret := make([]AttributeSpec, len(attrs))
|
|
for i, a := range attrs {
|
|
spec, err := d.GetAttribute(a)
|
|
if err != nil {
|
|
panic(fmt.Errorf("Error resolving Attribute %s: %s", a, err))
|
|
}
|
|
ret[i] = spec
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// ResolveAllAttributes returns every AttributeSpec
|
|
func ResolveAllAttributes(d DataGrid) []AttributeSpec {
|
|
return ResolveAttributes(d, d.AllAttributes())
|
|
}
|
|
|
|
func buildAttrSet(a []Attribute) map[Attribute]bool {
|
|
ret := make(map[Attribute]bool)
|
|
for _, a := range a {
|
|
ret[a] = true
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// AttributeIntersect returns the intersection of two Attribute slices.
|
|
//
|
|
// IMPORTANT: result is ordered in order of the first []Attribute argument.
|
|
//
|
|
// IMPORTANT: result contains only Attributes from a1.
|
|
func AttributeIntersect(a1, a2 []Attribute) []Attribute {
|
|
ret := make([]Attribute, 0)
|
|
for _, a := range a1 {
|
|
matched := false
|
|
for _, b := range a2 {
|
|
if a.Equals(b) {
|
|
matched = true
|
|
break
|
|
}
|
|
}
|
|
if matched {
|
|
ret = append(ret, a)
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// AttributeIntersectReferences returns the intersection of two Attribute slices.
|
|
//
|
|
// IMPORTANT: result is not guaranteed to be ordered.
|
|
//
|
|
// IMPORTANT: done using pointers for speed, use AttributeDifference
|
|
// if the Attributes originate from different DataGrids.
|
|
func AttributeIntersectReferences(a1, a2 []Attribute) []Attribute {
|
|
a1b := buildAttrSet(a1)
|
|
a2b := buildAttrSet(a2)
|
|
ret := make([]Attribute, 0)
|
|
for a := range a1b {
|
|
if _, ok := a2b[a]; ok {
|
|
ret = append(ret, a)
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// AttributeDifference returns the difference between two Attribute
|
|
// slices: i.e. all the values in a1 which do not occur in a2.
|
|
//
|
|
// IMPORTANT: result is ordered the same as a1.
|
|
//
|
|
// IMPORTANT: result only contains values from a1.
|
|
func AttributeDifference(a1, a2 []Attribute) []Attribute {
|
|
ret := make([]Attribute, 0)
|
|
for _, a := range a1 {
|
|
matched := false
|
|
for _, b := range a2 {
|
|
if a.Equals(b) {
|
|
matched = true
|
|
break
|
|
}
|
|
}
|
|
if !matched {
|
|
ret = append(ret, a)
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// AttributeDifferenceReferences returns the difference between two Attribute
|
|
// slices: i.e. all the values in a1 which do not occur in a2.
|
|
//
|
|
// IMPORTANT: result is not guaranteed to be ordered.
|
|
//
|
|
// IMPORTANT: done using pointers for speed, use AttributeDifference
|
|
// if the Attributes originate from different DataGrids.
|
|
func AttributeDifferenceReferences(a1, a2 []Attribute) []Attribute {
|
|
a1b := buildAttrSet(a1)
|
|
a2b := buildAttrSet(a2)
|
|
ret := make([]Attribute, 0)
|
|
for a := range a1b {
|
|
if _, ok := a2b[a]; !ok {
|
|
ret = append(ret, a)
|
|
}
|
|
}
|
|
return ret
|
|
}
|