Heim > Backend-Entwicklung > Golang > iter.json: Eine leistungsstarke und effiziente Möglichkeit, JSON in Go zu iterieren und zu bearbeiten

iter.json: Eine leistungsstarke und effiziente Möglichkeit, JSON in Go zu iterieren und zu bearbeiten

Barbara Streisand
Freigeben: 2024-12-27 15:25:10
Original
797 Leute haben es durchsucht

iter.json: A Powerful and Efficient Way to Iterate and Manipulate JSON in Go

Mussten Sie jemals unstrukturierte JSON-Daten in Go ändern? Vielleicht mussten Sie alle auf der schwarzen Liste stehenden Felder löschen, Schlüssel von „camelCase“ in „snake_case“ umbenennen oder alle Zahlen-IDs in Zeichenfolgen umwandeln, weil JavaScript int64 nicht mag? Wenn Ihre Lösung darin bestand, alles mithilfe von „encoding/json“ in eine Map[string]any zu entmarshalieren und es dann wieder zu marsalieren … nun, seien wir ehrlich, das ist alles andere als effizient!

Was wäre, wenn Sie die JSON-Daten durchlaufen, den Pfad jedes Elements erfassen und im Handumdrehen genau entscheiden könnten, was damit geschehen soll?

Ja! Ich habe eine gute Nachricht! Mit der neuen Iteratorfunktion in Go 1.23 gibt es eine bessere Möglichkeit, JSON zu iterieren und zu bearbeiten. Lernen Sie ezpkg.io/iter.json kennen – Ihren leistungsstarken und effizienten Begleiter für die Arbeit mit JSON in Go.


1. JSON iterieren

Vorausgesetzt, wir haben eine alice.json-Datei:

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

Zuerst verwenden wir for range Parse(), um die JSON-Datei zu durchlaufen, und geben dann den Pfad, den Schlüssel, das Token und die Ebene jedes Elements aus. Siehe Beispiele/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)
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

Der Code gibt Folgendes aus:

|         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 |
Nach dem Login kopieren
Nach dem Login kopieren

2. JSON erstellen

Verwenden Sie Builder, um JSON-Daten zu erstellen. Es akzeptiert optionale Argumente für die Einrückung. Siehe examples/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)
Nach dem Login kopieren
Nach dem Login kopieren

Das gibt den JSON mit Einrückung aus:

{
    "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
        }
    ]
}
Nach dem Login kopieren
Nach dem Login kopieren

3. JSON formatieren

Sie können JSON-Daten rekonstruieren oder formatieren, indem Sie deren Schlüssel und Werte an einen Builder senden. Siehe Beispiele/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)
}
Nach dem Login kopieren

Das erste Beispiel minimiert den JSON, während das zweite Beispiel ihn mit dem Präfix „?“ formatiert. in jeder Zeile.

--- 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
?       }
?   }
----------
Nach dem Login kopieren

4. Zeilennummern hinzufügen

In diesem Beispiel fügen wir der JSON-Ausgabe Zeilennummern hinzu, indem wir vor dem Aufruf von fmt.Fprintf() ein b.WriteNewline() hinzufügen. Siehe Beispiele/04.Zeilennummer.

// ?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)
Nach dem Login kopieren

Dies wird Folgendes ausgeben:

  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    }
Nach dem Login kopieren

5. Kommentare hinzufügen

Durch Einfügen eines fmt.Fprintf(comment) zwischen b.WriteComma() und b.WriteNewline() können Sie am Ende jeder Zeile einen Kommentar hinzufügen. Siehe Beispiele/05.Kommentar.

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)
Nach dem Login kopieren

Dies wird Folgendes ausgeben:

{                             //  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
Nach dem Login kopieren

6. JSON filtern und Werte extrahieren

Es gibt item.GetPathString() und item.GetRawPath(), um den Pfad des aktuellen Elements abzurufen. Sie können sie zum Filtern der JSON-Daten verwenden. Siehe Beispiele/06.filter_print.

Beispiel mit item.GetPathString() und 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())
}
Nach dem Login kopieren

Beispiel mit item.GetRawPath() und 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())
}
Nach dem Login kopieren

Beide Beispiele geben Folgendes aus:

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

7. JSON filtern und ein neues JSON zurückgeben

Durch die Kombination des Builders mit der Option SetSkipEmptyStructures(false) und der Filterlogik können Sie die JSON-Daten filtern und ein neues JSON zurückgeben. Siehe Beispiele/07.filter_json

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)
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

Dieses Beispiel gibt ein neues JSON mit nur den gefilterten Feldern zurück:

|         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 |
Nach dem Login kopieren
Nach dem Login kopieren

8. Werte bearbeiten

Dies ist ein Beispiel für die Bearbeitung von Werten in JSON-Daten. Gehen Sie davon aus, dass wir Nummern-IDs für unsere API verwenden. Die IDs sind zu groß und JavaScript kann sie nicht verarbeiten. Wir müssen sie in Strings konvertieren. Siehe Beispiele/08.number_id und order.json.

Durchlaufen Sie die JSON-Daten, finden Sie alle _id-Felder und konvertieren Sie die Nummern-IDs in Zeichenfolgen:

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)
Nach dem Login kopieren
Nach dem Login kopieren

Dadurch werden Anführungszeichen zu den Nummern-IDs hinzugefügt:

{
    "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
        }
    ]
}
Nach dem Login kopieren
Nach dem Login kopieren

Abschluss

Das Paket ezpkg.io/iter.json ermöglicht Go-Entwicklern den präzisen und effizienten Umgang mit JSON-Daten. Egal, ob Sie komplexe JSON-Strukturen durchlaufen, neue JSON-Objekte dynamisch erstellen, Daten formatieren oder minimieren, bestimmte Felder filtern oder sogar Werte transformieren müssen, iter.json bietet eine flexible und leistungsstarke Lösung.

Ich freue mich, dieses Paket mit der Community als Tool zur effektiven JSON-Manipulation zu teilen, ohne dass die Daten vollständig analysiert werden müssen. Obwohl es sich noch in einem frühen Entwicklungsstadium befindet und Raum für weitere Funktionen vorhanden ist, funktioniert es für viele gängige Anwendungsfälle bereits gut.

Wenn Sie spezielle Anforderungen oder Verbesserungsvorschläge haben, können Sie sich gerne an uns wenden – ich freue mich über Ihr Feedback und die Unterstützung Ihrer Anwendungsfälle! ?


Autor

Ich bin Oliver Nguyen .  Ein Softwareentwickler, der mit Go und JS arbeitet. Ich genieße es, zu lernen und jeden Tag eine bessere Version meiner selbst zu sehen. Gelegentlich Spin-off neuer Open-Source-Projekte. Teile Wissen und Gedanken während meiner Reise.

Der Beitrag wird auch auf olivernguyen.io veröffentlicht.

Das obige ist der detaillierte Inhalt voniter.json: Eine leistungsstarke und effiziente Möglichkeit, JSON in Go zu iterieren und zu bearbeiten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage