1package objx
2
3// Exclude returns a new Map with the keys in the specified []string
4// excluded.
5func (m Map) Exclude(exclude []string) Map {
6	excluded := make(Map)
7	for k, v := range m {
8		if !contains(exclude, k) {
9			excluded[k] = v
10		}
11	}
12	return excluded
13}
14
15// Copy creates a shallow copy of the Obj.
16func (m Map) Copy() Map {
17	copied := Map{}
18	for k, v := range m {
19		copied[k] = v
20	}
21	return copied
22}
23
24// Merge blends the specified map with a copy of this map and returns the result.
25//
26// Keys that appear in both will be selected from the specified map.
27// This method requires that the wrapped object be a map[string]interface{}
28func (m Map) Merge(merge Map) Map {
29	return m.Copy().MergeHere(merge)
30}
31
32// MergeHere blends the specified map with this map and returns the current map.
33//
34// Keys that appear in both will be selected from the specified map. The original map
35// will be modified. This method requires that
36// the wrapped object be a map[string]interface{}
37func (m Map) MergeHere(merge Map) Map {
38	for k, v := range merge {
39		m[k] = v
40	}
41	return m
42}
43
44// Transform builds a new Obj giving the transformer a chance
45// to change the keys and values as it goes. This method requires that
46// the wrapped object be a map[string]interface{}
47func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map {
48	newMap := Map{}
49	for k, v := range m {
50		modifiedKey, modifiedVal := transformer(k, v)
51		newMap[modifiedKey] = modifiedVal
52	}
53	return newMap
54}
55
56// TransformKeys builds a new map using the specified key mapping.
57//
58// Unspecified keys will be unaltered.
59// This method requires that the wrapped object be a map[string]interface{}
60func (m Map) TransformKeys(mapping map[string]string) Map {
61	return m.Transform(func(key string, value interface{}) (string, interface{}) {
62		if newKey, ok := mapping[key]; ok {
63			return newKey, value
64		}
65		return key, value
66	})
67}
68
69// Checks if a string slice contains a string
70func contains(s []string, e string) bool {
71	for _, a := range s {
72		if a == e {
73			return true
74		}
75	}
76	return false
77}
78