"Go getValueFromPath()"의 두 판 사이의 차이

 
(같은 사용자의 중간 판 4개는 보이지 않습니다)
2번째 줄: 2번째 줄:
;Go getValueFromPath()
;Go getValueFromPath()


==struct==
<syntaxhighlight lang='go'>
<syntaxhighlight lang='go'>
package main
package main
30번째 줄: 31번째 줄:
}
}


fmt.Println(getValueFromPath(user, ".X"))            // <nil>
fmt.Println(getValueFromPath(user, "X"))            // <nil>
fmt.Println(getValueFromPath(user, ".Name"))          // "John Doe"
fmt.Println(getValueFromPath(user, "Name"))          // "John Doe"
fmt.Println(getValueFromPath(user, ".Profile"))      // {john.doe@example.com 123-456-7890}
fmt.Println(getValueFromPath(user, "Profile"))      // {john.doe@example.com 123-456-7890}
fmt.Println(getValueFromPath(user, ".Profile.Email")) // "john.doe@example.com"
fmt.Println(getValueFromPath(user, "Profile.Email")) // "john.doe@example.com"
fmt.Println(getValueFromPath(user, ".Profile.Phone")) // "123-456-7890"
fmt.Println(getValueFromPath(user, "Profile.Phone")) // "123-456-7890"
}
}


func getValueFromPath(v interface{}, path string) interface{} {
func getValueFromPath(v interface{}, path string) interface{} {
fields := strings.Split(path[1:], ".")
fields := strings.Split(path, ".")
rv := reflect.ValueOf(v)
rv := reflect.ValueOf(v)
for _, field := range fields {
for _, field := range fields {
49번째 줄: 50번째 줄:
}
}
</syntaxhighlight>
</syntaxhighlight>
==json==
<syntaxhighlight lang='go'>
<syntaxhighlight lang='go'>
package main
package main


import (
import (
"encoding/json"
"fmt"
"fmt"
"reflect"
"reflect"
70번째 줄: 72번째 줄:


func main() {
func main() {
jsonData := `{
user := User{
"name": "John Doe",
Name: "John Doe",
"profile": {
Profile: Profile{
"email": "john.doe@example.com",
Email: "john.doe@example.com",
"phone": "123-456-7890"
Phone: "123-456-7890",
}
},
}`
 
var user User
if err := json.Unmarshal([]byte(jsonData), &user); err != nil {
fmt.Println("Error unmarshalling JSON:", err)
return
}
}


fmt.Println(getValueFromPath(user, ".name"))          // "John Doe"
fmt.Println(getValueFromPath(user, "x"))            // <nil>
fmt.Println(getValueFromPath(user, ".profile"))      // {john.doe@example.com 123-456-7890}
fmt.Println(getValueFromPath(user, "name"))          // "John Doe"
fmt.Println(getValueFromPath(user, ".profile.email")) // "john.doe@example.com"
fmt.Println(getValueFromPath(user, "profile"))      // {john.doe@example.com 123-456-7890}
fmt.Println(getValueFromPath(user, ".profile.phone")) // "123-456-7890"
fmt.Println(getValueFromPath(user, "profile.email")) // "john.doe@example.com"
fmt.Println(getValueFromPath(user, "profile.phone")) // "123-456-7890"
}
}


func getValueFromPath(v interface{}, path string) interface{} {
func getValueFromPath(v interface{}, path string) interface{} {
fields := strings.Split(strings.TrimPrefix(path, "."), ".")
fields := strings.Split(path, ".")
rv := reflect.ValueOf(v)
rv := reflect.ValueOf(v)


97번째 줄: 94번째 줄:
rv = reflect.Indirect(rv)
rv = reflect.Indirect(rv)


rt := rv.Type()
switch rv.Kind() {
found := false
case reflect.Struct:
rv = rv.FieldByNameFunc(func(name string) bool {
fieldType, _ := rv.Type().FieldByName(name)
jsonTag := fieldType.Tag.Get("json")
return jsonTag == field || strings.EqualFold(name, field)
})


for i := 0; i < rt.NumField(); i++ {
default:
structField := rt.Field(i)
return nil
jsonTag := structField.Tag.Get("json")
 
if jsonTag == field {
rv = rv.Field(i)
found = true
break
}
}
}


if !found || !rv.IsValid() {
if !rv.IsValid() {
return nil
return nil
}
}
119번째 줄: 114번째 줄:
}
}
</syntaxhighlight>
</syntaxhighlight>
==같이 보기==
* [[lodash get()]]


[[분류: Go 구조체]]
[[분류: Go 구조체]]

2025년 3월 11일 (화) 14:27 기준 최신판

1 개요[ | ]

Go getValueFromPath()

2 struct[ | ]

package main

import (
	"fmt"
	"reflect"
	"strings"
)

type User struct {
	Name    string
	Profile Profile
}

type Profile struct {
	Email string
	Phone string
}

func main() {
	user := User{
		Name: "John Doe",
		Profile: Profile{
			Email: "john.doe@example.com",
			Phone: "123-456-7890",
		},
	}

	fmt.Println(getValueFromPath(user, "X"))             // <nil>
	fmt.Println(getValueFromPath(user, "Name"))          // "John Doe"
	fmt.Println(getValueFromPath(user, "Profile"))       // {john.doe@example.com 123-456-7890}
	fmt.Println(getValueFromPath(user, "Profile.Email")) // "john.doe@example.com"
	fmt.Println(getValueFromPath(user, "Profile.Phone")) // "123-456-7890"
}

func getValueFromPath(v interface{}, path string) interface{} {
	fields := strings.Split(path, ".")
	rv := reflect.ValueOf(v)
	for _, field := range fields {
		rv = rv.FieldByName(field)
		if !rv.IsValid() {
			return nil
		}
	}
	return rv.Interface()
}

3 json[ | ]

package main

import (
	"fmt"
	"reflect"
	"strings"
)

type User struct {
	Name    string  `json:"name"`
	Profile Profile `json:"profile"`
}

type Profile struct {
	Email string `json:"email"`
	Phone string `json:"phone"`
}

func main() {
	user := User{
		Name: "John Doe",
		Profile: Profile{
			Email: "john.doe@example.com",
			Phone: "123-456-7890",
		},
	}

	fmt.Println(getValueFromPath(user, "x"))             // <nil>
	fmt.Println(getValueFromPath(user, "name"))          // "John Doe"
	fmt.Println(getValueFromPath(user, "profile"))       // {john.doe@example.com 123-456-7890}
	fmt.Println(getValueFromPath(user, "profile.email")) // "john.doe@example.com"
	fmt.Println(getValueFromPath(user, "profile.phone")) // "123-456-7890"
}

func getValueFromPath(v interface{}, path string) interface{} {
	fields := strings.Split(path, ".")
	rv := reflect.ValueOf(v)

	for _, field := range fields {
		rv = reflect.Indirect(rv)

		switch rv.Kind() {
		case reflect.Struct:
			rv = rv.FieldByNameFunc(func(name string) bool {
				fieldType, _ := rv.Type().FieldByName(name)
				jsonTag := fieldType.Tag.Get("json")
				return jsonTag == field || strings.EqualFold(name, field)
			})

		default:
			return nil
		}

		if !rv.IsValid() {
			return nil
		}
	}

	return rv.Interface()
}

4 같이 보기[ | ]

문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}