Pernahkah Anda perlu mengubah data JSON yang tidak terstruktur di Go? Mungkin Anda harus menghapus password dan semua kolom yang masuk daftar hitam, mengganti nama kunci dari camelCase menjadi snake_case , atau mengubah semua id angka menjadi string karena JavaScript tidak menyukai int64 ? Jika solusi Anda adalah dengan melakukan unmarshal semuanya ke map[string]any menggunakan encoding/json lalu melakukan marshal kembali... yah, jujur saja, itu jauh dari kata efisien! Bagaimana jika Anda dapat melakukan pengulangan melalui data JSON, mengambil jalur setiap item, dan memutuskan apa yang harus dilakukan dengannya saat itu juga? Ya! Saya punya kabar baik! Dengan fitur iterator baru di Go 1.23, ada cara yang lebih baik untuk mengulang dan memanipulasi JSON. Perkenalkan — pendamping Anda yang hebat dan efisien untuk bekerja dengan JSON di Go. ezpkg.io/iter.json 1. Mengulangi JSON Mengingat kita memiliki file : alice.json { "name": "Alice", "age": 24, "scores": [9, 10, 8], "address": { "city": "The Sun", "zip": 10101 } } Pertama, mari gunakan untuk mengulang file JSON, lalu cetak jalur, kunci, token, dan level setiap item. Lihat . for range Parse() examples/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) } } Kode akan menampilkan: | 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. Membangun JSON Gunakan untuk membuat data JSON. Builder menerima argumen opsional untuk indentasi. Lihat . Builder contoh/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", "alice@example.com") 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) Yang akan menampilkan JSON dengan indentasi: { "name": "Alice", "age": 22, "email": "alice@example.com", "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. Memformat JSON Anda dapat merekonstruksi atau memformat data JSON dengan mengirimkan kunci dan nilainya ke . Lihat . Builder contoh/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) } Contoh pertama memperkecil JSON sementara contoh kedua memformatnya dengan awalan "👉" pada setiap baris. --- 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. Menambahkan nomor baris Dalam contoh ini, kami menambahkan nomor baris ke output JSON, dengan menambahkan sebelum pemanggilan . Lihat . b.WriteNewline() fmt.Fprintf() contoh/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) Ini akan menampilkan: 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. Menambahkan komentar Dengan meletakkan di antara dan , Anda dapat menambahkan komentar di akhir setiap baris. Lihat . fmt.Fprintf(comment) b.WriteComma() b.WriteNewline() contoh/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) Ini akan menampilkan: { // 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. Memfilter JSON dan mengekstraksi nilai Ada dan untuk mendapatkan jalur item saat ini. Anda dapat menggunakannya untuk memfilter data JSON. Lihat . item.GetPathString() item.GetRawPath() contoh/06.filter_print Contoh dengan dan : item.GetPathString() 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()) } Contoh dengan dan : item.GetRawPath() 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()) } Kedua contoh akan menghasilkan: 2 "Alice" . name 9 { . address 10 "The Sun" . address.city 11 10101 . address.zip 12 } . address 7. Memfilter JSON dan mengembalikan JSON baru Dengan menggabungkan dengan opsi dan logika penyaringan, Anda dapat menyaring data JSON dan mengembalikan JSON baru. Lihat Builder SetSkipEmptyStructures(false) contoh/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) Contoh ini akan mengembalikan JSON baru hanya dengan bidang yang difilter: { "name": "Alice", "address": { "city": "The Sun", "zip": 10101 } } 8. Mengedit nilai Ini adalah contoh untuk mengedit nilai dalam data JSON. Asumsikan bahwa kita menggunakan id angka untuk API kita. Id tersebut terlalu besar dan JavaScript tidak dapat menanganinya. Kita perlu mengubahnya menjadi string. Lihat dan . contoh/08.number_id order.json Ulangi data JSON, temukan semua bidang dan ubah id angka menjadi string: _id 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) Ini akan menambahkan tanda kutip ke id nomor: { "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 } ] } Kesimpulan Paket memberdayakan pengembang Go untuk menangani data JSON dengan presisi dan efisiensi. Baik Anda perlu mengulangi struktur JSON yang kompleks, membuat objek JSON baru secara dinamis, memformat atau mengecilkan data, memfilter bidang tertentu, atau bahkan mengubah nilai, menawarkan solusi yang fleksibel dan canggih. ezpkg.io/iter.json iter.json Saya gembira dapat berbagi paket ini dengan komunitas sebagai alat untuk manipulasi JSON yang efektif tanpa perlu mengurai data secara menyeluruh. Meskipun masih dalam tahap pengembangan awal dan masih ada ruang untuk fitur-fitur lainnya, paket ini sudah berfungsi dengan baik untuk banyak kasus penggunaan umum. Jika Anda memiliki persyaratan khusus atau ide untuk perbaikan, jangan ragu untuk menghubungi saya — saya ingin mendengar masukan Anda dan membantu mendukung kasus penggunaan Anda! 🥳 Pengarang Saya Oliver Nguyen. Seorang insinyur perangkat lunak yang bekerja dengan Go dan JS. Saya senang belajar dan melihat versi diri saya yang lebih baik setiap hari. Sesekali membuat proyek sumber terbuka baru. Berbagi pengetahuan dan pemikiran selama perjalanan saya. Postingan ini juga dipublikasikan di oliverguyen.io .