func (c InterfaceSlice) Reduce(cb func(int, interface{}, interface{}) interface{}, defAgg ...interface{}) interface{} {
	var agg interface{}
	if len(defAgg) == 0 {
		agg = nil
	} else {
		agg = defAgg[0]
	}
	for k, v := range c {
		agg = cb(k, v, agg)
	}
	return agg
}
MapAsyncInterface method creates a new slice with the results of calling a provided go routine on every element in the calling array.
Runs asynchronously and needs gives a chan [2]interface{} to return results.
To keep initial order, the first elemt of th []interface{} written to the chan must be the key. The second element muse be a string.
Returns InterfaceSlice.
If you know the result will be of original type, user MapAsync.
package slices
import (
	"reflect"
	"github.com/francoispqt/lists"
)
type InterfaceSlice []interface{}
func (c InterfaceSlice) Contains(s interface{}) bool {
	contains := false
	for _, v := range c {
		val := reflect.ValueOf(v)
		sVal := reflect.ValueOf(s)
		switch val.Kind() {
		case reflect.Slice:
			if sVal.Kind() == reflect.Slice {
				contains = compare(v, s)
				if contains {
					return true
				}
			}
			continue
		case reflect.Array:
			if sVal.Kind() == reflect.Array {
				contains = compare(v, s)
				if contains {
					return true
				}
			}
			continue
		default:
			if v == s {
				return true
			}
		}
	}
	return contains
}
func (c InterfaceSlice) ForEach(cb func(int, interface{})) {
	for k, v := range c {
		cb(k, v)
	}
}
func (c InterfaceSlice) Map(cb func(int, interface{}) interface{}) InterfaceSlice {
	var ret = make([]interface{}, len(c))
	for k, v := range c {
		ret[k] = cb(k, v)
	}
	return ret
}
func (c InterfaceSlice) MapAsync(cb func(int, interface{}, chan [2]interface{}), maxConcurrency ...int) InterfaceSlice {
	var maxConc = lists.DEFAULT_CONC
	if len(maxConcurrency) == 1 {
		maxConc = maxConcurrency[0]
	}
	var mapChan = make(chan [2]interface{}, len(c))
	var doing chan struct{}
	var ret = make([]interface{}, len(c))
	var i = 0
	var received = 0
	if maxConc > 0 {
		doing = make(chan struct{}, maxConc)
	} else {
		doing = make(chan struct{})
	}
	for {
		if maxConc == 0 || (len(doing) < maxConc && i < len(c)) {
			v := c[i]
			go cb(i, v, mapChan)
			i++
			if maxConc > 0 {
				doing <- struct{}{}
			}
			if maxConc == 0 && i == len(c) {
				break
			}
		} else {
			intf := <-mapChan
			received++
			if len(intf) > 1 {
				ret[intf[0].(int)] = intf[1]
			} else {
				ret[intf[0].(int)] = nil
			}
			<-doing
			if received == len(c) {
				return ret
			}
		}
	}
	if maxConc == 0 {
		ct := 0
		for intf := range mapChan {
			if len(intf) > 1 {
				ret[intf[0].(int)] = intf[1]
			} else {
				ret[intf[0].(int)] = nil
			}
			ct++
			if ct >= len(c) {
				break
			}
		}
	}
	return ret
}