From f6826a1c977f1de5acee60dbd159fa31a41e1df2 Mon Sep 17 00:00:00 2001 From: Stefano Arlandini Date: Mon, 6 Mar 2023 10:55:57 +0100 Subject: [PATCH] Add function to cast `interface{}` to `[]float64` --- cast.go | 6 ++++++ cast_test.go | 39 +++++++++++++++++++++++++++++++++++++++ caste.go | 29 +++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/cast.go b/cast.go index 0cfe941..54737a7 100644 --- a/cast.go +++ b/cast.go @@ -169,6 +169,12 @@ func ToIntSlice(i interface{}) []int { return v } +// ToFloat64Slice casts an interface to a []float64 type. +func ToFloat64Slice(i interface{}) []float64 { + v, _ := ToFloat64SliceE(i) + return v +} + // ToDurationSlice casts an interface to a []time.Duration type. func ToDurationSlice(i interface{}) []time.Duration { v, _ := ToDurationSliceE(i) diff --git a/cast_test.go b/cast_test.go index 016f8c2..1a12f11 100644 --- a/cast_test.go +++ b/cast_test.go @@ -672,6 +672,45 @@ func TestToIntSliceE(t *testing.T) { } } +func TestToFloat64SliceE(t *testing.T) { + c := qt.New(t) + + tests := []struct { + input interface{} + expect []float64 + iserr bool + }{ + {[]int{1, 3}, []float64{1, 3}, false}, + {[]float64{1.2, 3.2}, []float64{1.2, 3.2}, false}, + {[]interface{}{1.2, 3.2}, []float64{1.2, 3.2}, false}, + {[]string{"2", "3"}, []float64{2, 3}, false}, + {[]string{"1.2", "3.2"}, []float64{1.2, 3.2}, false}, + {[2]string{"2", "3"}, []float64{2, 3}, false}, + {[2]string{"1.2", "3.2"}, []float64{1.2, 3.2}, false}, + // errors + {nil, nil, true}, + {testing.T{}, nil, true}, + {[]string{"foo", "bar"}, nil, true}, + } + + for i, test := range tests { + errmsg := qt.Commentf("i = %d", i) // assert helper message + + v, err := ToFloat64SliceE(test.input) + if test.iserr { + c.Assert(err, qt.IsNotNil) + continue + } + + c.Assert(err, qt.IsNil) + c.Assert(v, qt.DeepEquals, test.expect, errmsg) + + // Non-E test + v = ToFloat64Slice(test.input) + c.Assert(v, qt.DeepEquals, test.expect, errmsg) + } +} + func TestToSliceE(t *testing.T) { c := qt.New(t) diff --git a/caste.go b/caste.go index bccf27a..5690696 100644 --- a/caste.go +++ b/caste.go @@ -1340,6 +1340,35 @@ func ToIntSliceE(i interface{}) ([]int, error) { } } +// ToFloat64SliceE casts an interface to a []float64 type. +func ToFloat64SliceE(i interface{}) ([]float64, error) { + if i == nil { + return []float64{}, fmt.Errorf("unable to cast %#v of type %T to []float64", i, i) + } + + switch v := i.(type) { + case []float64: + return v, nil + } + + kind := reflect.TypeOf(i).Kind() + switch kind { + case reflect.Slice, reflect.Array: + s := reflect.ValueOf(i) + a := make([]float64, s.Len()) + for j := 0; j < s.Len(); j++ { + val, err := ToFloat64E(s.Index(j).Interface()) + if err != nil { + return []float64{}, fmt.Errorf("unable to cast %#v of type %T to []float64", i, i) + } + a[j] = val + } + return a, nil + default: + return []float64{}, fmt.Errorf("unable to cast %#v of type %T to []float64", i, i) + } +} + // ToDurationSliceE casts an interface to a []time.Duration type. func ToDurationSliceE(i interface{}) ([]time.Duration, error) { if i == nil {