把json中的全部key转化为驼峰式(首字母大写形式)

最近处理json数据,json中数据下划线形式,找了半天没有找到能把下划线处理成驼峰式的代码~ 自己动手!

功能:把例如 "the_red_apple":"very_nice" 转化为 "TheRedApple":"very_nice" 这种。

代码:https://github.com/SkyingzZ/camel_json_keys


//下划线写法转为驼峰写法	like "sample_test_name_balabala" to "SampleTestNameBalabala"
func CamelName(name string) string {
	name = strings.Replace(name, "_", " ", -1)
	name = strings.Title(name)
	return strings.Replace(name, " ", "", -1)
}

func CamelJsonKey(json_data []byte) []byte{
	str := string(json_data)

	var is_quot_first bool = true		//在双引号中为 false  	|	the value in the double quotes is false 
	var first_index int = 0				//左引号的索引			|	the left quote index
	var second_index int = 0			//右引号的索引			|	the right quote index

	var res_str string
	var the_key_index int
	for i, value := range str{
		if !is_quot_first && str[i] == '"'{		//右引号		|	if meet the right quote
			second_index = i
			is_quot_first = !is_quot_first
			
		}else if is_quot_first && str[i] == '"'{	//左引号	|	if meet the left quote
			first_index = i
			the_key_index = len(res_str)
			is_quot_first= !is_quot_first
		}else if is_quot_first && str[i] == ':'{	
			tmp_str := camelName(str[first_index+1: second_index])
			res_str = res_str[:the_key_index]+"\""+tmp_str+"\""
		}else{}

		res_str += string(value)
	}

	return []byte(res_str)
}

效果:

原来 ==> 后来

把json中的全部key转化为驼峰式(首字母大写形式)_第1张图片  把json中的全部key转化为驼峰式(首字母大写形式)_第2张图片

 

本来觉得上面这个一个for循环的代码虽然有很多数组的copy以及字符串的处理,但应该已经足够处理问题了。可终于在一个特殊的情况,遇到了一个6M大小的json字符串,此处理函数处理了10分钟。

于是对代码进行了改进,并换了一个使用map来处理的思路。下面这个代码,暂时业务中没遇到过超过ms级的情况。

同时,也得到了一点启迪,即在可以使用系统提供的底层情况下,尽量不要自己去写底层。因为不要觉得自己代码效率会超过大师。


//下划线写法转为驼峰写法,并且将'/'字符转换为''	like "sample_test_name_balabala/dilidili" to "SampleTestNameBalabalaDilidili"
//同时也会去掉左侧的全部数字	like "361_sport" to "Sport"
func camelName(name string) string {
    name = strings.Replace(name, "_", " ", -1)
    name = strings.Replace(name, "/", " ", -1)
    name = strings.Title(name)
    name = strings.Replace(name, " ", "", -1)
    return strings.TrimLeft(name, "0123456789")
}

func camelVecKey(my_vec []interface{}) ([]interface{}, error){
    if !strings.HasPrefix(reflect.TypeOf(my_vec).String(), "[]"){
        return nil, errors.New("decode to vector failed")
    }
    rtn_vec := my_vec[0:0]
    for _, node := range my_vec{
        if reflect.TypeOf(node) == nil{
            continue
        }
        if strings.HasPrefix(reflect.TypeOf(node).String(),"map"){
            res_node, err := camelMapKey(node.(map[string]interface{}))
            if err != nil{
                return nil, err
            }
            rtn_vec = append(rtn_vec, res_node)
        }else if strings.HasPrefix(reflect.TypeOf(node).String(),"[]"){
            res_node, err := camelVecKey(node.([]interface{}))
            if err != nil{
                return nil, err
            }
            rtn_vec = append(rtn_vec, res_node)
        }else{
            rtn_vec = append(rtn_vec, node)
        }
    }
    return rtn_vec, nil
}

func camelMapKey(my_map map[string]interface{}) (map[string]interface{}, error){

    if !strings.HasPrefix(reflect.TypeOf(my_map).String(), "map"){
        return nil, errors.New("decode to map failed")
    }
    rtn_map := make(map[string]interface{})
    for k,v := range my_map{
        if reflect.TypeOf(v) == nil{
            rtn_map[camelName(k)] = nil
            continue
        }
        if strings.HasPrefix(reflect.TypeOf(v).String(),"map"){
            res_map, err := camelMapKey(v.(map[string]interface{}))
            if err != nil{
                return nil, err
            }
            rtn_map[camelName(k)] = res_map
        } else if strings.HasPrefix(reflect.TypeOf(v).String(), "[]"){
           res_node, err := camelVecKey(v.([]interface{}))
           if err != nil{
               return nil, err
           }
           rtn_map[camelName(k)] = res_node
        } else {
            rtn_map[camelName(k)] = v
        }
    }
    return rtn_map, nil
}

func CamelJsonKey(json_data []byte, is_vec bool) ([]byte, error){
	var my_map_vec []interface{}
	var my_map map[string]interface{}
	if is_vec {
		err := json.Unmarshal(json_data, &my_map_vec)
		if err != nil{
			return []byte{}, errors.New("Unmarshal json to vector failed")
		}

		my_map_vec, err = camelVecKey(my_map_vec)
		if err != nil{
			return []byte{}, err
		}
		my_json,err :=json.Marshal(my_map_vec)
		if err != nil{
			return []byte{}, err
		}
		return my_json, err

	} else {
		my_map = make(map[string]interface{})
		err := json.Unmarshal(json_data, &my_map)
		if err != nil{
			return []byte{}, errors.New("Unmarshal json to map failed")
		}

		my_map, err = camelMapKey(my_map)
		if err != nil{
			return []byte{}, err
		}
		my_json,err :=json.Marshal(my_map)
		if err != nil{
			return []byte{}, err
		}
		return my_json, err
	}

}

 

你可能感兴趣的:(golang)