github.com/zhongdalu/gf@v1.0.0/g/util/gconv/gconv_slice.go (about)

     1  // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). 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/zhongdalu/gf.
     6  
     7  package gconv
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"reflect"
    13  
    14  	"github.com/zhongdalu/gf/g/internal/strutils"
    15  )
    16  
    17  // SliceInt is alias of Ints.
    18  func SliceInt(i interface{}) []int {
    19  	return Ints(i)
    20  }
    21  
    22  // SliceStr is alias of Strings.
    23  func SliceStr(i interface{}) []string {
    24  	return Strings(i)
    25  }
    26  
    27  // SliceAny is alias of Interfaces.
    28  func SliceAny(i interface{}) []interface{} {
    29  	return Interfaces(i)
    30  }
    31  
    32  // SliceFloat is alias of Floats.
    33  func SliceFloat(i interface{}) []float64 {
    34  	return Floats(i)
    35  }
    36  
    37  // SliceMap is alias of Maps.
    38  func SliceMap(i interface{}) []map[string]interface{} {
    39  	return Maps(i)
    40  }
    41  
    42  // SliceMapDeep is alias of MapsDeep.
    43  func SliceMapDeep(i interface{}) []map[string]interface{} {
    44  	return MapsDeep(i)
    45  }
    46  
    47  // SliceStruct is alias of Structs.
    48  func SliceStruct(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) {
    49  	return Structs(params, pointer, mapping...)
    50  }
    51  
    52  // SliceStructDeep is alias of StructsDeep.
    53  func SliceStructDeep(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) {
    54  	return StructsDeep(params, pointer, mapping...)
    55  }
    56  
    57  // Ints converts <i> to []int.
    58  func Ints(i interface{}) []int {
    59  	if i == nil {
    60  		return nil
    61  	}
    62  	if r, ok := i.([]int); ok {
    63  		return r
    64  	} else {
    65  		array := make([]int, 0)
    66  		switch value := i.(type) {
    67  		case []string:
    68  			for _, v := range value {
    69  				array = append(array, Int(v))
    70  			}
    71  		case []int8:
    72  			for _, v := range value {
    73  				array = append(array, Int(v))
    74  			}
    75  		case []int16:
    76  			for _, v := range value {
    77  				array = append(array, Int(v))
    78  			}
    79  		case []int32:
    80  			for _, v := range value {
    81  				array = append(array, Int(v))
    82  			}
    83  		case []int64:
    84  			for _, v := range value {
    85  				array = append(array, Int(v))
    86  			}
    87  		case []uint:
    88  			for _, v := range value {
    89  				array = append(array, Int(v))
    90  			}
    91  		case []uint8:
    92  			for _, v := range value {
    93  				array = append(array, Int(v))
    94  			}
    95  		case []uint16:
    96  			for _, v := range value {
    97  				array = append(array, Int(v))
    98  			}
    99  		case []uint32:
   100  			for _, v := range value {
   101  				array = append(array, Int(v))
   102  			}
   103  		case []uint64:
   104  			for _, v := range value {
   105  				array = append(array, Int(v))
   106  			}
   107  		case []bool:
   108  			for _, v := range value {
   109  				array = append(array, Int(v))
   110  			}
   111  		case []float32:
   112  			for _, v := range value {
   113  				array = append(array, Int(v))
   114  			}
   115  		case []float64:
   116  			for _, v := range value {
   117  				array = append(array, Int(v))
   118  			}
   119  		case []interface{}:
   120  			for _, v := range value {
   121  				array = append(array, Int(v))
   122  			}
   123  		case [][]byte:
   124  			for _, v := range value {
   125  				array = append(array, Int(v))
   126  			}
   127  		default:
   128  			return []int{Int(i)}
   129  		}
   130  		return array
   131  	}
   132  }
   133  
   134  // Strings converts <i> to []string.
   135  func Strings(i interface{}) []string {
   136  	if i == nil {
   137  		return nil
   138  	}
   139  	if r, ok := i.([]string); ok {
   140  		return r
   141  	} else {
   142  		array := make([]string, 0)
   143  		switch value := i.(type) {
   144  		case []int:
   145  			for _, v := range value {
   146  				array = append(array, String(v))
   147  			}
   148  		case []int8:
   149  			for _, v := range value {
   150  				array = append(array, String(v))
   151  			}
   152  		case []int16:
   153  			for _, v := range value {
   154  				array = append(array, String(v))
   155  			}
   156  		case []int32:
   157  			for _, v := range value {
   158  				array = append(array, String(v))
   159  			}
   160  		case []int64:
   161  			for _, v := range value {
   162  				array = append(array, String(v))
   163  			}
   164  		case []uint:
   165  			for _, v := range value {
   166  				array = append(array, String(v))
   167  			}
   168  		case []uint8:
   169  			for _, v := range value {
   170  				array = append(array, String(v))
   171  			}
   172  		case []uint16:
   173  			for _, v := range value {
   174  				array = append(array, String(v))
   175  			}
   176  		case []uint32:
   177  			for _, v := range value {
   178  				array = append(array, String(v))
   179  			}
   180  		case []uint64:
   181  			for _, v := range value {
   182  				array = append(array, String(v))
   183  			}
   184  		case []bool:
   185  			for _, v := range value {
   186  				array = append(array, String(v))
   187  			}
   188  		case []float32:
   189  			for _, v := range value {
   190  				array = append(array, String(v))
   191  			}
   192  		case []float64:
   193  			for _, v := range value {
   194  				array = append(array, String(v))
   195  			}
   196  		case []interface{}:
   197  			for _, v := range value {
   198  				array = append(array, String(v))
   199  			}
   200  		case [][]byte:
   201  			for _, v := range value {
   202  				array = append(array, String(v))
   203  			}
   204  		default:
   205  			return []string{String(i)}
   206  		}
   207  		return array
   208  	}
   209  }
   210  
   211  // Strings converts <i> to []float64.
   212  func Floats(i interface{}) []float64 {
   213  	if i == nil {
   214  		return nil
   215  	}
   216  	if r, ok := i.([]float64); ok {
   217  		return r
   218  	} else {
   219  		array := make([]float64, 0)
   220  		switch value := i.(type) {
   221  		case []string:
   222  			for _, v := range value {
   223  				array = append(array, Float64(v))
   224  			}
   225  		case []int:
   226  			for _, v := range value {
   227  				array = append(array, Float64(v))
   228  			}
   229  		case []int8:
   230  			for _, v := range value {
   231  				array = append(array, Float64(v))
   232  			}
   233  		case []int16:
   234  			for _, v := range value {
   235  				array = append(array, Float64(v))
   236  			}
   237  		case []int32:
   238  			for _, v := range value {
   239  				array = append(array, Float64(v))
   240  			}
   241  		case []int64:
   242  			for _, v := range value {
   243  				array = append(array, Float64(v))
   244  			}
   245  		case []uint:
   246  			for _, v := range value {
   247  				array = append(array, Float64(v))
   248  			}
   249  		case []uint8:
   250  			for _, v := range value {
   251  				array = append(array, Float64(v))
   252  			}
   253  		case []uint16:
   254  			for _, v := range value {
   255  				array = append(array, Float64(v))
   256  			}
   257  		case []uint32:
   258  			for _, v := range value {
   259  				array = append(array, Float64(v))
   260  			}
   261  		case []uint64:
   262  			for _, v := range value {
   263  				array = append(array, Float64(v))
   264  			}
   265  		case []bool:
   266  			for _, v := range value {
   267  				array = append(array, Float64(v))
   268  			}
   269  		case []float32:
   270  			for _, v := range value {
   271  				array = append(array, Float64(v))
   272  			}
   273  		case []interface{}:
   274  			for _, v := range value {
   275  				array = append(array, Float64(v))
   276  			}
   277  		default:
   278  			return []float64{Float64(i)}
   279  		}
   280  		return array
   281  	}
   282  }
   283  
   284  // Interfaces converts <i> to []interface{}.
   285  func Interfaces(i interface{}) []interface{} {
   286  	if i == nil {
   287  		return nil
   288  	}
   289  	if r, ok := i.([]interface{}); ok {
   290  		return r
   291  	} else {
   292  		array := make([]interface{}, 0)
   293  		switch value := i.(type) {
   294  		case []string:
   295  			for _, v := range value {
   296  				array = append(array, v)
   297  			}
   298  		case []int:
   299  			for _, v := range value {
   300  				array = append(array, v)
   301  			}
   302  		case []int8:
   303  			for _, v := range value {
   304  				array = append(array, v)
   305  			}
   306  		case []int16:
   307  			for _, v := range value {
   308  				array = append(array, v)
   309  			}
   310  		case []int32:
   311  			for _, v := range value {
   312  				array = append(array, v)
   313  			}
   314  		case []int64:
   315  			for _, v := range value {
   316  				array = append(array, v)
   317  			}
   318  		case []uint:
   319  			for _, v := range value {
   320  				array = append(array, v)
   321  			}
   322  		case []uint8:
   323  			for _, v := range value {
   324  				array = append(array, v)
   325  			}
   326  		case []uint16:
   327  			for _, v := range value {
   328  				array = append(array, v)
   329  			}
   330  		case []uint32:
   331  			for _, v := range value {
   332  				array = append(array, v)
   333  			}
   334  		case []uint64:
   335  			for _, v := range value {
   336  				array = append(array, v)
   337  			}
   338  		case []bool:
   339  			for _, v := range value {
   340  				array = append(array, v)
   341  			}
   342  		case []float32:
   343  			for _, v := range value {
   344  				array = append(array, v)
   345  			}
   346  		case []float64:
   347  			for _, v := range value {
   348  				array = append(array, v)
   349  			}
   350  		default:
   351  			// Finally we use reflection.
   352  			rv := reflect.ValueOf(i)
   353  			kind := rv.Kind()
   354  			// If it's pointer, find the real type.
   355  			if kind == reflect.Ptr {
   356  				rv = rv.Elem()
   357  				kind = rv.Kind()
   358  			}
   359  			switch kind {
   360  			case reflect.Slice, reflect.Array:
   361  				for i := 0; i < rv.Len(); i++ {
   362  					array = append(array, rv.Index(i).Interface())
   363  				}
   364  			case reflect.Struct:
   365  				rt := rv.Type()
   366  				for i := 0; i < rv.NumField(); i++ {
   367  					// Only public attributes.
   368  					if !strutils.IsLetterUpper(rt.Field(i).Name[0]) {
   369  						continue
   370  					}
   371  					array = append(array, rv.Field(i).Interface())
   372  				}
   373  			default:
   374  				return []interface{}{i}
   375  			}
   376  		}
   377  		return array
   378  	}
   379  }
   380  
   381  // Maps converts <i> to []map[string]interface{}.
   382  func Maps(value interface{}, tags ...string) []map[string]interface{} {
   383  	if value == nil {
   384  		return nil
   385  	}
   386  	if r, ok := value.([]map[string]interface{}); ok {
   387  		return r
   388  	} else {
   389  		array := Interfaces(value)
   390  		if len(array) == 0 {
   391  			return nil
   392  		}
   393  		list := make([]map[string]interface{}, len(array))
   394  		for k, v := range array {
   395  			list[k] = Map(v, tags...)
   396  		}
   397  		return list
   398  	}
   399  }
   400  
   401  // MapsDeep converts <i> to []map[string]interface{} recursively.
   402  func MapsDeep(value interface{}, tags ...string) []map[string]interface{} {
   403  	if value == nil {
   404  		return nil
   405  	}
   406  	if r, ok := value.([]map[string]interface{}); ok {
   407  		return r
   408  	} else {
   409  		array := Interfaces(value)
   410  		if len(array) == 0 {
   411  			return nil
   412  		}
   413  		list := make([]map[string]interface{}, len(array))
   414  		for k, v := range array {
   415  			list[k] = MapDeep(v, tags...)
   416  		}
   417  		return list
   418  	}
   419  }
   420  
   421  // Structs converts any slice to given struct slice.
   422  func Structs(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) {
   423  	return doStructs(params, pointer, false, mapping...)
   424  }
   425  
   426  // StructsDeep converts any slice to given struct slice recursively.
   427  func StructsDeep(params interface{}, pointer interface{}, mapping ...map[string]string) (err error) {
   428  	return doStructs(params, pointer, true, mapping...)
   429  }
   430  
   431  // doStructs converts any slice to given struct slice.
   432  //
   433  // The parameter <params> should be type of slice.
   434  //
   435  // The parameter <pointer> should be type of pointer to slice of struct.
   436  // Note that if <pointer> is a pointer to another pointer of type of slice of struct,
   437  // it will create the struct/pointer internally.
   438  func doStructs(params interface{}, pointer interface{}, deep bool, mapping ...map[string]string) (err error) {
   439  	if params == nil {
   440  		return errors.New("params cannot be nil")
   441  	}
   442  	if pointer == nil {
   443  		return errors.New("object pointer cannot be nil")
   444  	}
   445  	pointerRt := reflect.TypeOf(pointer)
   446  	if kind := pointerRt.Kind(); kind != reflect.Ptr {
   447  		return fmt.Errorf("pointer should be type of pointer, but got: %v", kind)
   448  	}
   449  
   450  	rv := reflect.ValueOf(params)
   451  	kind := rv.Kind()
   452  	if kind == reflect.Ptr {
   453  		rv = rv.Elem()
   454  		kind = rv.Kind()
   455  	}
   456  	switch kind {
   457  	case reflect.Slice, reflect.Array:
   458  		// If <params> is an empty slice, no conversion.
   459  		if rv.Len() == 0 {
   460  			return nil
   461  		}
   462  		array := reflect.MakeSlice(pointerRt.Elem(), rv.Len(), rv.Len())
   463  		itemType := array.Index(0).Type()
   464  		for i := 0; i < rv.Len(); i++ {
   465  			if itemType.Kind() == reflect.Ptr {
   466  				// Slice element is type pointer.
   467  				e := reflect.New(itemType.Elem()).Elem()
   468  				if deep {
   469  					if err = StructDeep(rv.Index(i).Interface(), e, mapping...); err != nil {
   470  						return err
   471  					}
   472  				} else {
   473  					if err = Struct(rv.Index(i).Interface(), e, mapping...); err != nil {
   474  						return err
   475  					}
   476  				}
   477  				array.Index(i).Set(e.Addr())
   478  			} else {
   479  				// Slice element is not type of pointer.
   480  				e := reflect.New(itemType).Elem()
   481  
   482  				if deep {
   483  					if err = StructDeep(rv.Index(i).Interface(), e, mapping...); err != nil {
   484  						return err
   485  					}
   486  				} else {
   487  					if err = Struct(rv.Index(i).Interface(), e, mapping...); err != nil {
   488  						return err
   489  					}
   490  				}
   491  				array.Index(i).Set(e)
   492  			}
   493  		}
   494  		reflect.ValueOf(pointer).Elem().Set(array)
   495  		return nil
   496  	default:
   497  		return fmt.Errorf("params should be type of slice, but got: %v", kind)
   498  	}
   499  }