常数时间搜索深层嵌套的JSON数据

huangapple go评论74阅读模式
英文:

Constant time search deeply nested JSON data

问题

我有一个嵌套的JSON结构,像下面这样。

{"object": 
    {
       "buffer_size": 10,
       "Databases":
       [
               {
                       "host": "localhost",
                       "user": "root",
                       "pass": "",
                       "type": "mysql",
                       "name": "go",
                       "Tables":
                       [
                               {
                                       "name": "testing",
                                       "statment": "teststring",
                                       "regex": "teststring ([0-9]+) ([A-z]+)",
                                       "Types": 
                                        [
                                           {
                                               "id": "1",
                                               "value": "string"
                                           },
                                           {
                                               "id": "2",
                                               "value": "string"
                                           },
                                           {
                                               "id": "3",
                                               "value": "string"
                                           }
                                        ]
                               }
                       ]
               }
       ]
    }
}

有没有办法使用常数时间查找Typesid并获取过滤后的结果,只输出那些扁平化的JSON中的结果,如下所示:

{
  "Types": [
     {"id": 1, "value": "string"},
     {"id": 2, "value": "string"},
     {"id": 3, "value": "string"}
  ]
}

我知道可以使用for循环来实现,但那样会花费很长时间。

英文:

I have a deeply nested structure of nested JSON like below.

{"object": 
    {
       "buffer_size": 10,
       "Databases":
       [
               {
                       "host": "localhost",
                       "user": "root",
                       "pass": "",
                       "type": "mysql",
                       "name": "go",
                       "Tables":
                       [
                               {
                                       "name": "testing",
                                       "statment": "teststring",
                                       "regex": "teststring ([0-9]+) ([A-z]+)",
                                       "Types": 
                                        [
                                           {
                                               "id": "1",
                                               "value": "string"
                                           },
                                           {
                                               "id": "2",
                                               "value": "string"
                                           },
                                           {
                                               "id": "3",
                                               "value": "string"
                                           }
                                        ]
                               }
                       ]
               }
       ]
    }
}

Is there a way I can use constant time lookup to search for id of Types and get the filtered results just for those ones with flattened JSON so that it outputs:

{
  "Types": [
     {"id": 1, "value": "string"}
     {"id": 2, "value": "string"}
     {"id": 3, "value": "string"}
  ]
}

I know I can achieve by using for loop but that would take long time.

答案1

得分: 1

这是我会做的方式:

type Id int

func (i *Id) UnmarshalJSON(b []byte) error {
	s := strings.Trim(string(b), `"`)
	id, err := strconv.Atoi(s)
	*i = Id(id)
	return err
}

type Type struct {
	Id    Id     `json:"id"`
	Value string `json:"value"`
}

func getTypes(b []byte) ([]Type, error) {
	var types = []Type{}
	var obj struct {
		Object struct {
			Databases []struct {
				Tables []struct {
					Types []Type `json:"Types"`
				} `json:"Tables"`
			} `json:"Databases"`
		} `json:"object"`
	}
	if err := json.Unmarshal(b, &obj); err != nil {
		return nil, err
	}
	for _, d := range obj.Object.Databases {
		for _, t := range d.Tables {
			types = append(types, t.Types...)
		}
	}
	return types, nil
}

func showTypes(types []Type) error {
	return json.NewEncoder(os.Stdout).Encode(struct {
		Types []Type `json:"Types"`
	}{types})
}

func main() {
	types, err := getTypes([]byte(data))
	if err != nil {
		log.Fatal(err)
	}
	if err := showTypes(types); err != nil {
		log.Fatal(err)
	}
}

至于常数时间,那是不可能的。

英文:

Here's how I'd do it:

type Id int

func (i *Id) UnmarshalJSON(b []byte) error {
	s := strings.Trim(string(b), `"`)
	id, err := strconv.Atoi(s)
	*i = Id(id)
	return err
}

type Type struct {
	Id    Id     `json:"id"`
	Value string `json:"value"`
}

func getTypes(b []byte) ([]Type, error) {
	var types = []Type{}
	var obj struct {
		Object struct {
			Databases []struct {
				Tables []struct {
					Types []Type `json:"Types"`
				} `json:"Tables"`
			} `json:"Databases"`
		} `json:"object"`
	}
	if err := json.Unmarshal(b, &obj); err != nil {
		return nil, err
	}
	for _, d := range obj.Object.Databases {
		for _, t := range d.Tables {
			types = append(types, t.Types...)
		}
	}
	return types, nil
}

func showTypes(types []Type) error {
	return json.NewEncoder(os.Stdout).Encode(struct {
		Types []Type `json:"Types"`
	}{types})
}

func main() {
	types, err := getTypes([]byte(data))
	if err != nil {
		log.Fatal(err)
	}
	if err := showTypes(types); err != nil {
		log.Fatal(err)
	}
}

As far as constant time goes, that's simply not possible.

huangapple
  • 本文由 发表于 2014年10月23日 13:47:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/26521982.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定