func (n *Node) Attribute(k string) string {
	return n.AttrMap[k]
}
Attribute returns value of attribute k.
package netmap
import (
	"strconv"
	"github.com/nspcc-dev/hrw"
	"github.com/nspcc-dev/neofs-api-go/v2/netmap"
)
type (
	Node struct {
		ID       uint64
		Index    int
		Capacity uint64
		Price    uint64
		AttrMap  map[string]string
		*NodeInfo
	}
	Nodes []*Node
)
type NodeState uint32
type NodeAttribute netmap.Attribute
type NodeInfo netmap.NodeInfo
const (
	_ NodeState = iota
	NodeStateOffline
	NodeStateOnline
)
const (
	AttrPrice = "Price"
	AttrCapacity = "Capacity"
	AttrSubnet = "Subnet"
	AttrUNLOCODE = "UN-LOCODE"
	AttrCountryCode = "CountryCode"
	AttrCountry = "Country"
	AttrLocation = "Location"
	AttrSubDivCode = "SubDivCode"
	AttrSubDiv = "SubDiv"
	AttrContinent = "Continent"
)
var _ hrw.Hasher = (*Node)(nil)
func (n Node) Hash() uint64 {
	return n.ID
}
func NodesFromInfo(infos []NodeInfo) Nodes {
	nodes := make(Nodes, len(infos))
	for i := range infos {
		nodes[i] = newNodeV2(i, &infos[i])
	}
	return nodes
}
func newNodeV2(index int, ni *NodeInfo) *Node {
	n := &Node{
		ID:       hrw.Hash(ni.PublicKey()),
		Index:    index,
		AttrMap:  make(map[string]string, len(ni.Attributes())),
		NodeInfo: ni,
	}
	for _, attr := range ni.Attributes() {
		switch attr.Key() {
		case AttrCapacity:
			n.Capacity, _ = strconv.ParseUint(attr.Value(), 10, 64)
		case AttrPrice:
			n.Price, _ = strconv.ParseUint(attr.Value(), 10, 64)
		}
		n.AttrMap[attr.Key()] = attr.Value()
	}
	return n
}
func (n Nodes) Weights(wf weightFunc) []float64 {
	w := make([]float64, 0, len(n))
	for i := range n {
		w = append(w, wf(n[i]))
	}
	return w
}