1package funk 2 3import ( 4 "reflect" 5) 6 7// Compact creates a slice with all empty/zero values removed. 8func Compact(value interface{}) interface{} { 9 arr := redirectValue(reflect.ValueOf(value)) 10 11 if arr.Kind() != reflect.Slice && arr.Kind() != reflect.Array { 12 panic("First parameter must be array or slice") 13 } 14 15 sliceElemType := sliceElem(arr.Type()) 16 resultSliceType := reflect.SliceOf(sliceElemType) 17 result := reflect.MakeSlice(resultSliceType, 0, 0) 18 19 for i := 0; i < arr.Len(); i++ { 20 elemVal := arr.Index(i) 21 22 if elemVal.Kind() == reflect.Interface { 23 elemVal = elemVal.Elem() 24 } 25 26 redirectedElemVal := redirectValue(elemVal) 27 28 switch redirectedElemVal.Kind() { 29 case reflect.Invalid: 30 continue 31 case reflect.Func: 32 if redirectedElemVal.IsNil() { 33 continue 34 } 35 case reflect.Map, reflect.Slice, reflect.Chan: 36 if redirectedElemVal.Len() == 0 { 37 continue 38 } 39 default: 40 defaultValue := reflect.Zero(redirectedElemVal.Type()).Interface() 41 if redirectedElemVal.Interface() == defaultValue { 42 continue 43 } 44 } 45 46 result = reflect.Append(result, elemVal) 47 } 48 49 return result.Interface() 50} 51