...

Source file src/github.com/thoas/go-funk/builder.go

Documentation: github.com/thoas/go-funk

     1  package funk
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  )
     7  
     8  // Builder contains all tools which can be chained.
     9  type Builder interface {
    10  	Chunk(size int) Builder
    11  	Compact() Builder
    12  	Drop(n int) Builder
    13  	Filter(predicate interface{}) Builder
    14  	Flatten() Builder
    15  	FlattenDeep() Builder
    16  	Initial() Builder
    17  	Intersect(y interface{}) Builder
    18  	Join(rarr interface{}, fnc JoinFnc) Builder
    19  	Map(mapFunc interface{}) Builder
    20  	FlatMap(mapFunc interface{}) Builder
    21  	Reverse() Builder
    22  	Shuffle() Builder
    23  	Tail() Builder
    24  	Uniq() Builder
    25  	Without(values ...interface{}) Builder
    26  
    27  	All() bool
    28  	Any() bool
    29  	Contains(elem interface{}) bool
    30  	Every(elements ...interface{}) bool
    31  	Find(predicate interface{}) interface{}
    32  	ForEach(predicate interface{})
    33  	ForEachRight(predicate interface{})
    34  	Head() interface{}
    35  	Keys() interface{}
    36  	IndexOf(elem interface{}) int
    37  	IsEmpty() bool
    38  	Last() interface{}
    39  	LastIndexOf(elem interface{}) int
    40  	NotEmpty() bool
    41  	Product() float64
    42  	Reduce(reduceFunc, acc interface{}) interface{}
    43  	Sum() float64
    44  	Type() reflect.Type
    45  	Value() interface{}
    46  	Values() interface{}
    47  }
    48  
    49  // Chain creates a simple new go-funk.Builder from a collection. Each method 
    50  // call generate a new builder containing the previous result.
    51  func Chain(v interface{}) Builder {
    52  	isNotNil(v, "Chain")
    53  
    54  	valueType := reflect.TypeOf(v)
    55  	if isValidBuilderEntry(valueType) ||
    56  		(valueType.Kind() == reflect.Ptr && isValidBuilderEntry(valueType.Elem())) {
    57  		return &chainBuilder{v}
    58  	}
    59  
    60  	panic(fmt.Sprintf("Type %s is not supported by Chain", valueType.String()))
    61  }
    62  
    63  // LazyChain creates a lazy go-funk.Builder from a collection. Each method call
    64  // generate a new builder containing a method generating the previous value.
    65  // With that, all data are only generated when we call a tailling method like All or Find.
    66  func LazyChain(v interface{}) Builder {
    67  	isNotNil(v, "LazyChain")
    68  
    69  	valueType := reflect.TypeOf(v)
    70  	if isValidBuilderEntry(valueType) ||
    71  		(valueType.Kind() == reflect.Ptr && isValidBuilderEntry(valueType.Elem())) {
    72  		return &lazyBuilder{func() interface{} { return v }}
    73  	}
    74  
    75  	panic(fmt.Sprintf("Type %s is not supported by LazyChain", valueType.String()))
    76  
    77  }
    78  
    79  // LazyChainWith creates a lazy go-funk.Builder from a generator. Like LazyChain, each 
    80  // method call generate a new builder containing a method generating the previous value.
    81  // But, instead of using a collection, it takes a generator which can generate values.
    82  // With LazyChainWith, to can create a generic pipeline of collection transformation and, 
    83  // throw the generator, sending different collection.
    84  func LazyChainWith(generator func() interface{}) Builder {
    85  	isNotNil(generator, "LazyChainWith")
    86  	return &lazyBuilder{func() interface{} {
    87  		isNotNil(generator, "LazyChainWith")
    88  
    89  		v := generator()
    90  		valueType := reflect.TypeOf(v)
    91  		if isValidBuilderEntry(valueType) ||
    92  			(valueType.Kind() == reflect.Ptr && isValidBuilderEntry(valueType.Elem())) {
    93  			return v
    94  		}
    95  
    96  		panic(fmt.Sprintf("Type %s is not supported by LazyChainWith generator", valueType.String()))
    97  	}}
    98  }
    99  
   100  func isNotNil(v interface{}, from string) {
   101  	if v == nil {
   102  		panic(fmt.Sprintf("nil value is not supported by %s", from))
   103  	}
   104  }
   105  
   106  func isValidBuilderEntry(valueType reflect.Type) bool {
   107  	return valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Array ||
   108  		valueType.Kind() == reflect.Map ||
   109  		valueType.Kind() == reflect.String
   110  }
   111  

View as plain text