FilterMap receives a map with string keys and arbitrary values (possibly other maps) and return a new map which is a subset of the original one containing only the keys matching any of the patterns in "include" and excluding keys matching any of the patterns in "exclude". The logic for determining i
(m map[string]interface{}, include, exclude []string)
| 39 | // resulting map, as long as it doesn't match a pattern in "exclude". |
| 40 | // |
| 41 | func FilterMap(m map[string]interface{}, include, exclude []string) map[string]interface{} { |
| 42 | includeGlob := make([]glob.Glob, len(include)) |
| 43 | excludeGlob := make([]glob.Glob, len(exclude)) |
| 44 | for i, p := range include { |
| 45 | cp := glob.MustCompile(p, '.') |
| 46 | includeGlob[i] = cp |
| 47 | } |
| 48 | // For each include pattern that do not ends with **, add the same pattern |
| 49 | // but ended in .**. This because when someone says that she wants to include |
| 50 | // "foo.bar", where "foo.bar" is dictionary, what she actually expects is |
| 51 | // getting the dictionary with all its keys, but the keys inside the |
| 52 | // dictionary don't match the "foo.bar" pattern, so we add "foo.bar.**". |
| 53 | for _, p := range include { |
| 54 | if !strings.HasSuffix(p, "**") { |
| 55 | includeGlob = append(includeGlob, glob.MustCompile(p+".**", '.')) |
| 56 | } |
| 57 | } |
| 58 | for i, p := range exclude { |
| 59 | cp := glob.MustCompile(p, '.') |
| 60 | excludeGlob[i] = cp |
| 61 | } |
| 62 | // The same happens if you exclude "foo.bar", what you actually mean is |
| 63 | // excluding "foo.bar" and "foo.bar.**". |
| 64 | for _, p := range exclude { |
| 65 | if !strings.HasSuffix(p, "**") { |
| 66 | excludeGlob = append(excludeGlob, glob.MustCompile(p+".**", '.')) |
| 67 | } |
| 68 | } |
| 69 | filtered := filterMap(reflect.ValueOf(m), includeGlob, excludeGlob, "") |
| 70 | return filtered.Interface().(map[string]interface{}) |
| 71 | } |
| 72 | |
| 73 | // actualValue returns v if it's not an interface. If v is an interface it |
| 74 | // returns the value pointed to by the interface. |