paint-brush
Nova značajka u Gou olakšava ponavljanje i manipuliranje JSON podacimapo@olvrng
Nova povijest

Nova značajka u Gou olakšava ponavljanje i manipuliranje JSON podacima

po Oliver Nguyen13m2024/12/17
Read on Terminal Reader

Predugo; Čitati

Što kada biste mogli proći kroz svoje JSON podatke, uhvatiti putanju svake stavke i u hodu točno odlučiti što s njom učiniti?
featured image - Nova značajka u Gou olakšava ponavljanje i manipuliranje JSON podacima
Oliver Nguyen HackerNoon profile picture

Jeste li ikada morali modificirati nestrukturirane JSON podatke u Go? Možda ste morali izbrisati lozinku i sva polja s crne liste, preimenovati ključeve iz camelCase u snake_case ili pretvoriti sve ID-ove brojeva u nizove jer JavaScript ne voli int64 ? Ako je vaše rješenje bilo demarširati sve u map[string]any pomoću encoding/json i zatim to marširati natrag... pa, budimo iskreni, to je daleko od učinkovitog!


Što ako možete proći kroz JSON podatke, uhvatiti putanju svake stavke i odlučiti točno što ćete s njom u hodu?


Da! Imam dobre vijesti! S novom značajkom iteratora u Go 1.23, postoji bolji način za ponavljanje i manipuliranje JSON-om. Upoznajte ezpkg.io/iter.json — vašeg moćnog i učinkovitog suputnika za rad s JSON-om u Go-u.


1. Ponavljanje JSON-a

S obzirom da imamo datoteku alice.json :

 { "name": "Alice", "age": 24, "scores": [9, 10, 8], "address": { "city": "The Sun", "zip": 10101 } }


Prvo, upotrijebimo for range Parse() za iteraciju po JSON datoteci, a zatim ispišite putanju, ključ, token i razinu svake stavke. Vidi primjere/01.iter .

 package main import ( "fmt" "ezpkg.io/errorz" iterjson "ezpkg.io/iter.json" ) func main() { data := `{"name": "Alice", "age": 24, "scores": [9, 10, 8], "address": {"city": "The Sun", "zip": 10101}}` // 🎄Example: iterate over json fmt.Printf("| %12v | %10v | %10v |%v|\n", "PATH", "KEY", "TOKEN", "LVL") fmt.Println("| ------------ | ---------- | ---------- | - |") for item, err := range iterjson.Parse([]byte(data)) { errorz.MustZ(err) fmt.Printf("| %12v | %10v | %10v | %v |\n", item.GetPathString(), item.Key, item.Token, item.Level) } }


Kod će ispisati:

 | PATH | KEY | TOKEN |LVL| | ------------ | ---------- | ---------- | - | | | | { | 0 | | name | "name" | "Alice" | 1 | | age | "age" | 24 | 1 | | scores | "scores" | [ | 1 | | scores.0 | | 9 | 2 | | scores.1 | | 10 | 2 | | scores.2 | | 8 | 2 | | scores | | ] | 1 | | address | "address" | { | 1 | | address.city | "city" | "The Sun" | 2 | | address.zip | "zip" | 10101 | 2 | | address | | } | 1 | | | | } | 0 |

2. Izrada JSON-a

Koristite Builder za izradu JSON podataka. Prihvaća neobavezne argumente za uvlačenje. Vidi primjere/02.builder .

 b := iterjson.NewBuilder("", " ") // open an object b.Add("", iterjson.TokenObjectOpen) // add a few fields b.Add("name", "Alice") b.Add("age", 22) b.Add("email", "[email protected]") b.Add("phone", "(+84) 123-456-789") // open an array b.Add("languages", iterjson.TokenArrayOpen) b.Add("", "English") b.Add("", "Vietnamese") b.Add("", iterjson.TokenArrayClose) // close the array // accept any type that can marshal to json b.Add("address", Address{ HouseNumber: 42, Street: "Ly Thuong Kiet", City: "Ha Noi", Country: "Vietnam", }) // accept []byte as raw json b.Add("pets", []byte(`[{"type":"cat","name":"Kitty","age":2},{"type":"dog","name":"Yummy","age":3}]`)) // close the object b.Add("", iterjson.TokenObjectClose) out := errorz.Must(b.Bytes()) fmt.Printf("\n--- build json ---\n%s\n", out)


Što će ispisati JSON s uvlakom:

 { "name": "Alice", "age": 22, "email": "[email protected]", "phone": "(+84) 123-456-789", "languages": [ "English", "Vietnamese" ], "address": {"house_number":42,"street":"Ly Thuong Kiet","city":"Ha Noi","country":"Vietnam"}, "pets": [ { "type": "cat", "name": "Kitty", "age": 2 }, { "type": "dog", "name": "Yummy", "age": 3 } ] }

3. Formatiranje JSON-a

Možete rekonstruirati ili formatirati JSON podatke slanjem ključa i vrijednosti Builder u. Vidi primjere/03.reformat .

 { // 🐝Example: minify json b := iterjson.NewBuilder("", "") for item, err := range iterjson.Parse(data) { errorz.MustZ(err) b.AddRaw(item.Key, item.Token) } out := errorz.Must(b.Bytes()) fmt.Printf("\n--- minify ---\n%s\n----------\n", out) } { // 🦋Example: format json b := iterjson.NewBuilder("👉 ", "\t") for item, err := range iterjson.Parse(data) { errorz.MustZ(err) b.AddRaw(item.Key, item.Token) } out := errorz.Must(b.Bytes()) fmt.Printf("\n--- reformat ---\n%s\n----------\n", out) }


Prvi primjer minimizira JSON dok ga drugi primjer formatira s prefiksom "👉" u svakom retku.

 --- minify --- {"name":"Alice","age":24,"scores":[9,10,8],"address":{"city":"The Sun","zip":10101}} ---------- --- reformat --- 👉 { 👉 "name": "Alice", 👉 "age": 24, 👉 "scores": [ 👉 9, 👉 10, 👉 8 👉 ], 👉 "address": { 👉 "city": "The Sun", 👉 "zip": 10101 👉 } 👉 } ----------

4. Dodavanje brojeva redaka

U ovom primjeru JSON izlazu dodajemo brojeve redaka dodavanjem b.WriteNewline() prije poziva fmt.Fprintf() . Vidi examples/04.line_number .

 // 🐞Example: print with line number i := 0 b := iterjson.NewBuilder("", " ") for item, err := range iterjson.Parse(data) { i++ errorz.MustZ(err) b.WriteNewline(item.Token.Type()) // 👉 add line number fmt.Fprintf(b, "%3d ", i) b.Add(item.Key, item.Token) } out := errorz.Must(b.Bytes()) fmt.Printf("\n--- line number ---\n%s\n----------\n", out)


Ovo će ispisati:

 1 { 2 "name": "Alice", 3 "age": 24, 4 "scores": [ 5 9, 6 10, 7 8 8 ], 9 "address": { 10 "city": "The Sun", 11 "zip": 10101 12 } 13 }

5. Dodavanje komentara

Stavljanjem fmt.Fprintf(comment) između b.WriteComma() i b.WriteNewline() , možete dodati komentar na kraj svakog retka. Vidi examples/05.comment .

 i, newlineIdx, maxIdx := 0, 0, 30 b := iterjson.NewBuilder("", " ") for item, err := range iterjson.Parse(data) { errorz.MustZ(err) b.WriteComma(item.Token.Type()) // 👉 add comment if i > 0 { length := b.Len() - newlineIdx fmt.Fprint(b, strings.Repeat(" ", maxIdx-length)) fmt.Fprintf(b, "// %2d", i) } i++ b.WriteNewline(item.Token.Type()) newlineIdx = b.Len() // save the newline index b.Add(item.Key, item.Token) } length := b.Len() - newlineIdx fmt.Fprint(b, strings.Repeat(" ", maxIdx-length)) fmt.Fprintf(b, "// %2d", i) out := errorz.Must(b.Bytes()) fmt.Printf("\n--- comment ---\n%s\n----------\n", out)


Ovo će ispisati:

 { // 1 "name": "Alice", // 2 "age": 24, // 3 "scores": [ // 4 9, // 5 10, // 6 8 // 7 ], // 8 "address": { // 9 "city": "The Sun", // 10 "zip": 10101 // 11 } // 12 } // 13

6. Filtriranje JSON-a i izdvajanje vrijednosti

Postoje item.GetPathString() i item.GetRawPath() za dobivanje putanje trenutne stavke. Možete ih koristiti za filtriranje JSON podataka. Pogledajte primjere/06.filter_print .


Primjer s item.GetPathString() i regexp :

 fmt.Printf("\n--- filter: GetPathString() ---\n") i := 0 for item, err := range iterjson.Parse(data) { i++ errorz.MustZ(err) path := item.GetPathString() switch { case path == "name", strings.Contains(path, "address"): // continue default: continue } // 👉 print with line number fmt.Printf("%2d %20s . %s\n", i, item.Token, item.GetPath()) }


Primjer s item.GetRawPath() i path.Match() :

 fmt.Printf("\n--- filter: GetRawPath() ---\n") i := 0 for item, err := range iterjson.Parse(data) { i++ errorz.MustZ(err) path := item.GetRawPath() switch { case path.Match("name"), path.Contains("address"): // continue default: continue } // 👉 print with line number fmt.Printf("%2d %20s . %s\n", i, item.Token, item.GetPath()) }


Oba će primjera ispisati:

 2 "Alice" . name 9 { . address 10 "The Sun" . address.city 11 10101 . address.zip 12 } . address

7. Filtriranje JSON-a i vraćanje novog JSON-a

Kombiniranjem Builder s opcijom SetSkipEmptyStructures(false) i logikom filtriranja, možete filtrirati JSON podatke i vratiti novi JSON. Pogledajte primjere/07.filter_json

 // 🦁Example: filter and output json b := iterjson.NewBuilder("", " ") b.SetSkipEmptyStructures(true) // 👉 skip empty [] or {} for item, err := range iterjson.Parse(data) { errorz.MustZ(err) if item.Token.IsOpen() || item.Token.IsClose() { b.Add(item.Key, item.Token) continue } path := item.GetPathString() switch { case path == "name", strings.Contains(path, "address"): // continue default: continue } b.Add(item.Key, item.Token) } out := errorz.Must(b.Bytes()) fmt.Printf("\n--- filter: output json ---\n%s\n----------\n", out)


Ovaj će primjer vratiti novi JSON samo s filtriranim poljima:

 { "name": "Alice", "address": { "city": "The Sun", "zip": 10101 } }

8. Uređivanje vrijednosti

Ovo je primjer za uređivanje vrijednosti u JSON podacima. Pretpostavimo da koristimo identifikacijske brojeve brojeva za naš API. ID-ovi su preveliki i JavaScript ih ne može obraditi. Moramo ih pretvoriti u nizove. Pogledajte examples/08.number_id i order.json .


Iterirajte JSON podatke, pronađite sva _id polja i pretvorite brojeve ID-ova u nizove:

 b := iterjson.NewBuilder("", " ") for item, err := range iterjson.Parse(data) { errorz.MustZ(err) key, _ := item.GetRawPath().Last().ObjectKey() if strings.HasSuffix(key, "_id") { id, err0 := item.Token.GetInt() if err0 == nil { b.Add(item.Key, strconv.Itoa(id)) continue } } b.Add(item.Key, item.Token) } out := errorz.Must(b.Bytes()) fmt.Printf("\n--- convert number id ---\n%s\n----------\n", out)


Ovo će dodati navodnike ID-ovima brojeva:

 { "order_id": "12345678901234", "number": 12, "customer_id": "12345678905678", "items": [ { "item_id": "12345678901042", "quantity": 1, "price": 123.45 }, { "item_id": "12345678901098", "quantity": 2, "price": 234.56 } ] }

Zaključak

Paket ezpkg.io/iter.json omogućuje Go programerima da precizno i učinkovito rukuju JSON podacima. Bilo da trebate iterirati kroz složene JSON strukture, dinamički graditi nove JSON objekte, formatirati ili minimizirati podatke, filtrirati određena polja ili čak transformirati vrijednosti, iter.json nudi fleksibilno i snažno rješenje.


Uzbuđen sam što mogu sa zajednicom podijeliti ovaj paket kao alat za učinkovitu manipulaciju JSON-om bez potrebe za potpunim analiziranjem podataka. Iako je još uvijek u ranom razvoju i ima mjesta za više značajki, već dobro radi u mnogim uobičajenim slučajevima upotrebe.


Ako imate specifične zahtjeve ili ideje za poboljšanje, slobodno se obratite — volio bih čuti vaše povratne informacije i pomoći u vašim slučajevima upotrebe! 🥳



Autor

Ja sam Oliver Nguyen. Softverski inženjer koji radi s Go i JS. Uživam učiti i vidjeti bolju verziju sebe svaki dan. Povremeno pokrenuti nove projekte otvorenog koda. Dijelite znanje i misli tijekom mog putovanja.


Post je također objavljen na olivernguyen.io .

L O A D I N G
. . . comments & more!

About Author

Oliver Nguyen HackerNoon profile picture
Oliver Nguyen@olvrng
I’m a software maker working mostly in Go and JavaScript. Share knowledge and thoughts during my journey.

VIJESI OZNAKE

OVAJ ČLANAK JE PREDSTAVLJEN U...