github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/util/generic/merge_reduce.go (about)

     1  package generic
     2  
     3  func Merge(collection, otherCollection Map) Map {
     4  	mergedMap := NewMap()
     5  
     6  	iterator := func(key, value interface{}) {
     7  		mergedMap.Set(key, value)
     8  	}
     9  
    10  	Each(collection, iterator)
    11  	Each(otherCollection, iterator)
    12  
    13  	return mergedMap
    14  }
    15  
    16  func DeepMerge(maps ...Map) Map {
    17  	mergedMap := NewMap()
    18  	return Reduce(maps, mergedMap, mergeReducer)
    19  }
    20  
    21  func mergeReducer(key, val interface{}, reduced Map) Map {
    22  	switch {
    23  	case reduced.Has(key) == false:
    24  		reduced.Set(key, val)
    25  		return reduced
    26  
    27  	case IsMappable(val):
    28  		maps := []Map{NewMap(reduced.Get(key)), NewMap(val)}
    29  		mergedMap := Reduce(maps, NewMap(), mergeReducer)
    30  		reduced.Set(key, mergedMap)
    31  		return reduced
    32  
    33  	case IsSliceable(val):
    34  		reduced.Set(key, append(reduced.Get(key).([]interface{}), val.([]interface{})...))
    35  		return reduced
    36  
    37  	default:
    38  		reduced.Set(key, val)
    39  		return reduced
    40  	}
    41  }
    42  
    43  type Reducer func(key, val interface{}, reducedVal Map) Map
    44  
    45  func Reduce(collections []Map, resultVal Map, cb Reducer) Map {
    46  	for _, collection := range collections {
    47  		for _, key := range collection.Keys() {
    48  			resultVal = cb(key, collection.Get(key), resultVal)
    49  		}
    50  	}
    51  	return resultVal
    52  }