diff --git a/redis/reply.go b/redis/reply.go index 20232e70..5ece6d55 100644 --- a/redis/reply.go +++ b/redis/reply.go @@ -476,6 +476,36 @@ func Int64Map(result interface{}, err error) (map[string]int64, error) { return m, nil } +// Float64Map is a helper that converts an array of strings (alternating key, value) +// into a map[string]float64. The HGETALL commands return replies in this format. +// Requires an even number of values in result. +func Float64Map(result interface{}, err error) (map[string]float64, error) { + values, err := Values(result, err) + if err != nil { + return nil, err + } + + if len(values)%2 != 0 { + return nil, fmt.Errorf("redigo: Float64Map expects even number of values result, got %d", len(values)) + } + + m := make(map[string]float64, len(values)/2) + for i := 0; i < len(values); i += 2 { + key, ok := values[i].([]byte) + if !ok { + return nil, fmt.Errorf("redigo: Float64Map key[%d] not a bulk string value, got %T", i, values[i]) + } + + value, err := Float64(values[i+1], nil) + if err != nil { + return nil, err + } + + m[string(key)] = value + } + return m, nil +} + // Positions is a helper that converts an array of positions (lat, long) // into a [][2]float64. The GEOPOS command returns replies in this format. func Positions(result interface{}, err error) ([]*[2]float64, error) { diff --git a/redis/reply_test.go b/redis/reply_test.go index 8993bad1..8f43828c 100644 --- a/redis/reply_test.go +++ b/redis/reply_test.go @@ -123,6 +123,11 @@ var replyTests = []struct { ve(redis.Float64(nil, nil)), ve(float64(0.0), redis.ErrNil), }, + { + "float64Map([[]byte, []byte])", + ve(redis.Float64Map([]interface{}{[]byte("key1"), []byte("1.234"), []byte("key2"), []byte("5.678")}, nil)), + ve(map[string]float64{"key1": 1.234, "key2": 5.678}, nil), + }, { "uint64(1)", ve(redis.Uint64(int64(1), nil)),