func (c IntSlice) ReduceAsync(cb func(int, int, *lists.AsyncAggregator), defAgg ...interface{}) interface{} {
	agg := &lists.AsyncAggregator{
		Done: make(chan interface{}, len(c)),
		Agg:  make(chan interface{}, len(c)),
	}
	if len(defAgg) == 0 {
		agg.Agg <- nil
	} else {
		agg.Agg <- defAgg[0]
	}
	for k, v := range c {
		go cb(k, v, agg)
		agg.Agg <- <-agg.Done
	}
	return <-agg.Agg
}
Reduce method applies a go routinge against an accumulator and each element in the slice (from left to right) to reduce it to a single value of any type.
Returns an interface.
For synchronicity, see Reduce.
package slices
import "github.com/francoispqt/lists"
type IntSlice []int
func (c IntSlice) Contains(s int) bool {
	for _, v := range c {
		if v == s {
			return true
		}
	}
	return false
}
func (c IntSlice) ForEach(cb func(int, int)) {
	for k, v := range c {
		cb(k, v)
	}
}
func (c IntSlice) Map(cb func(int, int) int) IntSlice {
	var ret = make([]int, len(c))
	for k, v := range c {
		ret[k] = cb(k, v)
	}
	return ret
}
func (c IntSlice) MapInterface(cb func(int, int) interface{}) InterfaceSlice {
	var ret = make([]interface{}, len(c))
	for k, v := range c {
		ret[k] = cb(k, v)
	}
	return ret
}
func (c IntSlice) MapAsync(cb func(int, int, chan [2]int), maxConcurrency ...int) IntSlice {
	var maxConc = lists.DEFAULT_CONC
	if len(maxConcurrency) == 1 {
		maxConc = maxConcurrency[0]
	}
	var mapChan = make(chan [2]int, len(c))
	var doing chan struct{}
	var ret = make([]int, 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]] = intf[1]
			} else {
				ret[intf[0]] = 0
			}
			<-doing
			if received == len(c) {
				return ret
			}
		}
	}
	if maxConc == 0 {
		ct := 0
		for intf := range mapChan {
			if len(intf) > 1 {
				ret[intf[0]] = intf[1]
			} else {
				ret[intf[0]] = 0
			}
			ct++
			if ct >= len(c) {
				break
			}
		}
	}
	return ret
}
func (c IntSlice) MapAsyncInterface(cb func(int, int, 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
}
func (c IntSlice) Reduce(cb func(int, int, 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
}