1
0
mirror of https://github.com/sjwhitworth/golearn.git synced 2025-04-26 13:49:14 +08:00
golearn/base/util_attributes.go
2014-08-03 15:17:42 +01:00

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
}