Example #1
0
// MapEquiv returns true if its arguments are equivalent as maps.
// First argument is an iseq.PMap.
// Second argument must be convertible to a map. (Someeday we may handle go maps.)
// To be equivalent, must contain equivalent keys and values.
func MapEquiv(m1 iseq.PMap, obj interface{}) bool {
	if m1 == obj {
		return true
	}

	if _, ok := obj.(map[interface{}]interface{}); ok {
		// TODO: figure out how to handle go maps
		return false
	}

	if m2, ok := obj.(iseq.PMap); ok {
		if m1.Count() != m2.Count() {
			return false
		}

		for s := m1.Seq(); s != nil; s = s.Next() {
			me := s.First().(iseq.MapEntry)
			found := m2.ContainsKey(me.Key())
			if !found || !Equiv(me.Val(), m2.ValAt(me.Key())) {
				return false
			}
		}
		return true
	}
	return false
}
Example #2
0
// MapCons adds (conses) a new key/value pair onto an iseq.PMap
// A MapEntry adds its key/value.
// A PVector uses v[2*i] v[2*i+1] as key/value pairs
// Otherwise, we need a sequence of iseq.MapEntry values
// Assumes its argument is one of the above; else panics
func MapCons(m iseq.PMap, o interface{}) iseq.PMap {
	if me, ok := o.(iseq.MapEntry); ok {
		return m.AssocM(me.Key(), me.Val())
	}

	if v, ok := o.(iseq.PVector); ok {
		if v.Count() != 2 {
			panic("Vector arg to map cons must be a pair")
		}
		return m.AssocM(v.Nth(0), v.Nth(1))
	}

	ret := m
	for s := ConvertToSeq(o); s != nil; s = s.Next() {
		me := s.First().(iseq.MapEntry)
		ret = ret.AssocM(me.Key(), me.Val())
	}
	return ret
}
Example #3
0
// HashMap computes a hash for an iseq.PMap
func HashMap(m iseq.PMap) uint32 {
	return HashUnordered(m.Seq())
}