func (cmd *Command) Exec(c *Crowd) error { if c.data == nil { return errors.New("Exec: Data is empty") } l := c.Len() if cmd.CommandType == CommandSum { fn := cmd.Fns[0] sum := float64(0) for i := 0; i < l; i++ { el := fn(c.Item(i)) if !toolkit.IsNumber(el) { c.Result.Sum = 0 return nil } item := toolkit.ToFloat64(el, 4, toolkit.RoundingAuto) sum += item } c.Result.Sum = sum } else if cmd.CommandType == CommandMin { fn := cmd.Fns[0] var ret interface{} for i := 0; i < l; i++ { item := fn(c.Item(i)) if i == 0 { ret = item } else if toolkit.Compare(ret, item, "$gt") { ret = item } } c.Result.Min = ret } else if cmd.CommandType == CommandMax { fn := cmd.Fns[0] var ret interface{} for i := 0; i < l; i++ { item := fn(c.Item(i)) if i == 0 { ret = item } else if toolkit.Compare(ret, item, "$lt") { ret = item } } c.Result.Max = ret } else if cmd.CommandType == CommandAvg { fn := cmd.Fns[0] ret := float64(0) for i := 0; i < l; i++ { el := fn(c.Item(i)) if !toolkit.IsNumber(el) { c.Result.Sum = 0 return nil } item := toolkit.ToFloat64(el, 4, toolkit.RoundingAuto) ret += item } c.Result.Avg = ret / toolkit.ToFloat64(l, 0, toolkit.RoundingAuto) } else if cmd.CommandType == CommandWhere { fn := cmd.Fns[0] el, _ := toolkit.GetEmptySliceElement(c.data) tel := reflect.TypeOf(el) array := reflect.MakeSlice(reflect.SliceOf(tel), 0, 0) for i := 0; i < l; i++ { item := c.Item(i) if fn(item).(bool) { array = reflect.Append(array, reflect.ValueOf(item)) } } c.Result.data = array.Interface() } else if cmd.CommandType == CommandApply { fn := cmd.Fns[0] var array reflect.Value for i := 0; i < l; i++ { item := fn(c.Item(i)) if i == 0 { //toolkit.Println(reflect.ValueOf(item).Type().String()) array = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(item)), 0, 0) } else { array = reflect.Append(array, reflect.ValueOf(item)) } } c.Result.data = array.Interface() c.data = c.Result.data } else if cmd.CommandType == CommandGroup { fng := cmd.Fns[0] fnc := cmd.Fns[1] mvs := map[interface{}]reflect.Value{} //mvo := map[interface{}]interface{}{} var mvo []KV for i := 0; i < l; i++ { item := c.Item(i) g := fng(item) gi := fnc(item) array, exist := mvs[g] if !exist { //array = []interface{}{} array = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(gi)), 0, 0) } array = reflect.Append(array, reflect.ValueOf(gi)) //toolkit.Println("Data:",g,array) mvs[g] = array } for k, v := range mvs { mvo = append(mvo, KV{k, v.Interface()}) } c.Result.data = mvo c.data = mvo } else { return errors.New(string(cmd.CommandType) + ": not yet applicable") } return nil }
func (cmd *Command) Exec(c *Crowd) error { if c.data == nil { return errors.New("Exec: Data is empty") } l := c.Len() if cmd.CommandType == CommandSum { fn := cmd.Fns[0] sum := float64(0) for i := 0; i < l; i++ { el := fn(c.Item(i)) if !toolkit.IsNumber(el) { c.Result.Sum = 0 return nil } item := toolkit.ToFloat64(el, 4, toolkit.RoundingAuto) sum += item } c.Result.Sum = sum } else if cmd.CommandType == CommandMin { fn := cmd.Fns[0] var ret interface{} for i := 0; i < l; i++ { item := fn(c.Item(i)) if i == 0 { ret = item } else if toolkit.Compare(ret, item, "$gt") { ret = item } } c.Result.Min = ret } else if cmd.CommandType == CommandMax { fn := cmd.Fns[0] var ret interface{} for i := 0; i < l; i++ { item := fn(c.Item(i)) if i == 0 { ret = item } else if toolkit.Compare(ret, item, "$lt") { ret = item } } c.Result.Max = ret } else if cmd.CommandType == CommandAvg { fn := cmd.Fns[0] ret := float64(0) for i := 0; i < l; i++ { el := fn(c.Item(i)) if !toolkit.IsNumber(el) { c.Result.Sum = 0 return nil } item := toolkit.ToFloat64(el, 4, toolkit.RoundingAuto) ret += item } c.Result.Avg = toolkit.Div(ret, toolkit.ToFloat64(l, 0, toolkit.RoundingAuto)) } else if cmd.CommandType == CommandWhere { fn := cmd.Fns[0] el, _ := toolkit.GetEmptySliceElement(c.data) tel := reflect.TypeOf(el) array := reflect.MakeSlice(reflect.SliceOf(tel), 0, 0) for i := 0; i < l; i++ { item := c.Item(i) if fn(item).(bool) { //toolkit.Printfn("Where data %d: %v", i, item) array = reflect.Append(array, reflect.ValueOf(item)) } } c.Result.data = array.Interface() } else if cmd.CommandType == CommandApply { fn := cmd.Fns[0] var array reflect.Value for i := 0; i < l; i++ { item := fn(c.Item(i)) //toolkit.Printfn("Applying data %d of %d: %v", i, l, item) if i == 0 { //toolkit.Println(reflect.ValueOf(item).Type().String()) array = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(item)), 0, 0) } array = reflect.Append(array, reflect.ValueOf(item)) } c.Result.data = array.Interface() c.data = c.Result.data } else if cmd.CommandType == CommandGroup { fng := cmd.Fns[0] fnc := cmd.Fns[1] mvs := map[interface{}]reflect.Value{} //mvo := map[interface{}]interface{}{} var mvo []KV for i := 0; i < l; i++ { item := c.Item(i) //toolkit.Printfn("Processing data %d of %d: %v", i, l, item) g := fng(item) gi := fnc(item) array, exist := mvs[g] if !exist { //array = []interface{}{} array = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(gi)), 0, 0) } array = reflect.Append(array, reflect.ValueOf(gi)) //toolkit.Println("Data:",g,array) mvs[g] = array } for k, v := range mvs { mvo = append(mvo, KV{k, v.Interface()}) } c.Result.data = mvo c.data = mvo } else if cmd.CommandType == CommandSort { sorter, e := NewSorter(c.data, cmd.Fns[0]) if e != nil { return e } var direction SortDirection direction = cmd.Parms.Get("direction", SortAscending).(SortDirection) c.Result.data = sorter.Sort(direction) c.data = c.Result.data } else if cmd.CommandType == CommandJoin { joinData := cmd.Parms.Get("joindata") if joinData == nil { return errors.New("crowd.join: Right side join data is nil") } if cmd.FnJoinKey == nil { cmd.FnJoinKey = func(x, y interface{}) bool { return x == y } } if cmd.FnJoinSelect == nil { cmd.FnJoinSelect = func(x, y interface{}) interface{} { return toolkit.M{}.Set("data1", x).Set("data2", y) } } l1 := toolkit.SliceLen(joinData) var array reflect.Value arrayBuilt := false for i := 0; i < l; i++ { item1 := c.Item(i) for i1 := 0; i1 < l1; i1++ { item2 := toolkit.SliceItem(joinData, i1) joinOK := cmd.FnJoinKey(item1, item2) if joinOK { outObj := cmd.FnJoinSelect(item1, item2) if !arrayBuilt { arrayBuilt = true array = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(outObj)), 0, 0) } array = reflect.Append(array, reflect.ValueOf(outObj)) } } } if !arrayBuilt { return errors.New("crowd.join: No match") } c.Result.data = array.Interface() c.data = array.Interface() } else { return errors.New(string(cmd.CommandType) + ": not yet applicable") } return nil }