package main
import (
"fmt"
"reflect"
"sync"
"sync/atomic"
)
func Omit(src interface{}, fields []string) (map[string]interface{}, error) {
var (
mutex *sync.RWMutex = &sync.RWMutex{}
safeValueAssignMap *atomic.Value = &atomic.Value{}
safeValueMap *atomic.Value = &atomic.Value{}
maps map[string]interface{} = make(map[string]interface{})
)
if ok := reflect.ValueOf(src).CanConvert(reflect.TypeOf(maps)); !ok {
return nil, fmt.Errorf("src must be a map type not %s", reflect.ValueOf(src).Kind().String())
}
srcValueMaps, err := InterfaceToMap(src)
if err != nil {
return nil, err
}
mapLength := len(reflect.ValueOf(srcValueMaps).MapKeys()) - len(fields)
for k, v := range srcValueMaps {
assingMap := make(map[string]interface{}, mapLength)
safeValueAssignMap.Store(assingMap)
for i := 0; i < len(fields); i++ {
if srcValueMaps[fields[i]] == v {
delete(maps, fields[i])
break
} else {
mutex.Lock()
assingMap[k] = v
maps, err = MergeMap(maps, safeValueAssignMap.Load())
if err != nil {
return nil, err
}
safeValueMap.Store(maps)
mutex.Unlock()
defer func() {
assingMap = nil
}()
}
}
}
defer func() {
maps = nil
}()
return safeValueMap.Load().(map[string]interface{}), nil
}
func main() {
body := make(map[string]interface{})
body["name"] = "john doe"
body["age"] = 23
body["address"] = "jl.arif rahman"
body["city"] = "depok"
body["country"] = "indonesia"
body["state"] = "jawa barat"
body["postcode"] = "14436"
res, err := OmitForMap(body, []string{"name", "age", "address"})
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(res)
}