github.com/gogf/gf@v1.16.9/util/gconv/gconv_maps.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gconv
     8  
     9  import "github.com/gogf/gf/internal/json"
    10  
    11  // SliceMap is alias of Maps.
    12  func SliceMap(any interface{}) []map[string]interface{} {
    13  	return Maps(any)
    14  }
    15  
    16  // SliceMapDeep is alias of MapsDeep.
    17  func SliceMapDeep(any interface{}) []map[string]interface{} {
    18  	return MapsDeep(any)
    19  }
    20  
    21  // SliceStruct is alias of Structs.
    22  func SliceStruct(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) {
    23  	return Structs(params, pointer, mapping...)
    24  }
    25  
    26  // Maps converts `value` to []map[string]interface{}.
    27  // Note that it automatically checks and converts json string to []map if `value` is string/[]byte.
    28  func Maps(value interface{}, tags ...string) []map[string]interface{} {
    29  	if value == nil {
    30  		return nil
    31  	}
    32  	switch r := value.(type) {
    33  	case string:
    34  		list := make([]map[string]interface{}, 0)
    35  		if len(r) > 0 && r[0] == '[' && r[len(r)-1] == ']' {
    36  			if err := json.UnmarshalUseNumber([]byte(r), &list); err != nil {
    37  				return nil
    38  			}
    39  			return list
    40  		} else {
    41  			return nil
    42  		}
    43  
    44  	case []byte:
    45  		list := make([]map[string]interface{}, 0)
    46  		if len(r) > 0 && r[0] == '[' && r[len(r)-1] == ']' {
    47  			if err := json.UnmarshalUseNumber(r, &list); err != nil {
    48  				return nil
    49  			}
    50  			return list
    51  		} else {
    52  			return nil
    53  		}
    54  
    55  	case []map[string]interface{}:
    56  		return r
    57  
    58  	default:
    59  		array := Interfaces(value)
    60  		if len(array) == 0 {
    61  			return nil
    62  		}
    63  		list := make([]map[string]interface{}, len(array))
    64  		for k, v := range array {
    65  			list[k] = Map(v, tags...)
    66  		}
    67  		return list
    68  	}
    69  }
    70  
    71  // MapsDeep converts `value` to []map[string]interface{} recursively.
    72  //
    73  // TODO completely implement the recursive converting for all types.
    74  func MapsDeep(value interface{}, tags ...string) []map[string]interface{} {
    75  	if value == nil {
    76  		return nil
    77  	}
    78  	switch r := value.(type) {
    79  	case string:
    80  		list := make([]map[string]interface{}, 0)
    81  		if len(r) > 0 && r[0] == '[' && r[len(r)-1] == ']' {
    82  			if err := json.UnmarshalUseNumber([]byte(r), &list); err != nil {
    83  				return nil
    84  			}
    85  			return list
    86  		} else {
    87  			return nil
    88  		}
    89  
    90  	case []byte:
    91  		list := make([]map[string]interface{}, 0)
    92  		if len(r) > 0 && r[0] == '[' && r[len(r)-1] == ']' {
    93  			if err := json.UnmarshalUseNumber(r, &list); err != nil {
    94  				return nil
    95  			}
    96  			return list
    97  		} else {
    98  			return nil
    99  		}
   100  
   101  	case []map[string]interface{}:
   102  		list := make([]map[string]interface{}, len(r))
   103  		for k, v := range r {
   104  			list[k] = MapDeep(v, tags...)
   105  		}
   106  		return list
   107  
   108  	default:
   109  		array := Interfaces(value)
   110  		if len(array) == 0 {
   111  			return nil
   112  		}
   113  		list := make([]map[string]interface{}, len(array))
   114  		for k, v := range array {
   115  			list[k] = MapDeep(v, tags...)
   116  		}
   117  		return list
   118  	}
   119  }