func (jp *JPath) Find(path string) (interface{}, error) { keys := strings.Split(path, jp.Separator) index := len(keys) - 1 //路径的尽头
m := jp.data for i, v := range keys { if m == nil { return nil, errors.New(fmt.Sprintf("path %+v not found ", path)) } //数组判断 if !strings.HasSuffix(v, ARRAY_TYPE_SUFFIX) { data := m[v] //到达了要寻找的路径末尾 if i == index { if data == nil { return nil, errors.New(fmt.Sprintf("path %+v not found ", path)) } return data, nil } //path中这个节点并不是数组也不是路径的结尾、只需要处理字符串和map的情况 switch data.(type) { case map[string]interface{}: m = data.(map[string]interface{}) case string: m_sub, _ := strToMap(m[v].(string), false) m[v] = m_sub m = m_sub case []interface{}: return nil, errors.New(fmt.Sprintf("key %+v error,array should be like this [index]", path))
default: return nil, errors.New(fmt.Sprintf("key %+v error,it is not string or map", v)) } } else { //匹配出[index] flag := ARRAY_REGEX.FindString(v) value, err := strconv.Atoi(flag[1 : len(flag)-1]) if err != nil { return nil, errors.New(fmt.Sprintf("illegal index args %+v", flag)) } key := strings.Split(v, flag)[0] //获取数组路径的前缀、例如simple[1]中的simple data := m[key] //这段路径被用户作为数组传入、只需要处理数组的情况 switch data.(type) { case []interface{}: arr := data.([]interface{}) if value > len(arr)-1 { return nil, errors.New(fmt.Sprintf("key %+v error,it is larger than array last index %+v", v, len(arr)-1)) } tmp := arr[value] if i == index { if tmp == nil { return nil, errors.New(fmt.Sprintf("path %+v not found ", path)) } return tmp, nil } //对数组中取出的值、要进行再次判断、因为它并不是路径的最后、需要再生成一个map以便于获取下一层value switch tmp.(type) { case map[string]interface{}: m = tmp.(map[string]interface{}) case string: m_sub, _ := strToMap(tmp.(string), false) m[v] = m_sub m = m_sub default: return nil, errors.New(fmt.Sprintf("key %+v error,it is not string or map", v)) } //在并发场景下、会需要将map完全递归生成。会有这种类型、统一处理了 case []map[string]interface{}:
arr := data.([]map[string]interface{}) if value > len(arr)-1 { return nil, errors.New(fmt.Sprintf("key %+v error,it is larger than array last index %+v", v, len(arr)-1)) } tmp := arr[value] if i == index { if tmp == nil { return nil, errors.New(fmt.Sprintf("path %+v not found ", path)) } return tmp, nil }
m = tmp
default: return nil, errors.New(fmt.Sprintf("key %+v error,it is not a array", v))
} } }
return nil, errors.New(fmt.Sprintf("path %+v not found ", path))}
评论