Maison  >  Article  >  développement back-end  >  Comment faire une itération imbriquée

Comment faire une itération imbriquée

WBOY
WBOYavant
2024-02-14 16:50:09767parcourir

Comment faire une itération imbriquée

l'éditeur php Youzi vous présentera comment effectuer une itération imbriquée. L'itération imbriquée est une technique consistant à utiliser une autre boucle dans une boucle, ce qui nous aide à gérer des structures de données complexes ou des tableaux multidimensionnels. Lorsque nous effectuons des itérations imbriquées, nous devons prêter attention à l'ordre et aux conditions des boucles pour garantir que chaque élément est accessible et traité correctement. Cet article expliquera en détail les principes et l'utilisation de l'itération imbriquée et fournira quelques exemples pratiques à titre de référence. Que vous soyez débutant ou développeur expérimenté, cet article peut vous aider à mieux comprendre et appliquer les techniques d'itération imbriquée. Explorons ensemble !

Contenu de la question

J'essaie de développer une extension vers un autre logiciel qui envoie des requêtes à une application écrite en go. Dans un programme go (que j'appellerai maintenant un "programme"), l'un des objectifs est de convertir un fichier json dans un format itérable. Voici un exemple du format json que j'utilise :

{
  "name": "game-name",
  "tree": {
    "$classname": "datamodel",

    "replicatedstorage": {
      "$path": "src/replicatedstorage"
    },

    "serverscriptservice": {
      "$path": "src/serverscriptservice"
    },

    "replicatedfirst": {
      "$path": "src/replicatedfirst"
    },

    "serverstorage": {
      "$path": "src/serverstorage"
    }
  }
}

L'idée est :

  • L'itération peut obtenir "nom"
  • L'itération peut obtenir "$classname"
  • Pour toutes les instances indexées par "$path", le nom du dossier dans le parent src 文件夹下创建一个文件夹,其中包含父地图的索引。例如,replicatedstorage 是路径为 src/replicatedstorage sera trouvé

Voici une fonction de gestionnaire pour faire cela :

func process(in interface{}) {
v := reflect.ValueOf(in)

    if v.Kind() == reflect.Map {
        for _, key := range v.MapKeys() {
            strct := v.MapIndex(key)
    
            index := key.Interface()
            value := reflect.ValueOf(strct.Interface())
    
            if index == "tree" {
                for _, treeKey := range value.MapKeys() {
                    treeIndex := treeKey.Interface()
    
                    fmt.Println("KEY")
                    fmt.Println(treeIndex)
    
                    if treeIndex != "$className" {
                        fmt.Println("bug")
                        fmt.Println(treeKey)
    
                        a := key.MapIndex(value) // panic serving ...: reflect: call of reflect.Value.MapIndex on string Value
                        b := reflect.ValueOf(a.Interface())
    
                        for _, key2 := range b.MapKeys() {
                            index2 := key2.Interface()
                            value2 := reflect.ValueOf(key2.Interface())
    
                            fmt.Println(index2)
                            fmt.Println(value2)
                        }
                    }
                }
            }
        }
    }

}

Les commentaires ont souligné un emplacement et un contenu incorrects. Une chose que j'aimerais aussi faire est de ne pas avoir à empiler les boucles for, car c'est un très mauvais code.

Solution de contournement

L'approche habituelle consiste à désorganiser le type go qui correspond à la structure des données. Le problème ici est que l'arborescence ne peut pas être facilement représentée comme un type go (elle a un champ $classname de type chaîne, mais est par ailleurs similaire à une carte avec une valeur d'objet contenant un champ $path).

Continuons à désorganiser en interface{} comme vous l'avez déjà fait.

Utilisez des tapez des assertions au lieu de packages de réflexion. Utilisez Map Index pour rechercher des valeurs au lieu de parcourir les clés et de trouver des correspondances.

func process(in interface{}) error {
    top, ok := in.(map[string]interface{})
    if !ok {
        return errors.New("expected object at top level")
    }
    tree, ok := top["tree"].(map[string]interface{})
    if !ok {
        return errors.New(".tree not found")
    }
    name, ok := top["name"]
    if !ok {
        return errors.New(".name not found")
    }
    className, ok := tree["$className"].(string)
    if !ok {
        return errors.New(".tree.$className not found")
    }
    for k, v := range tree {
        thing, ok := v.(map[string]interface{})
        if !ok {
            continue
        }
        path, ok := thing["$path"].(string)
        if !ok {
            continue
        }
        fmt.Println(name, className, k, path)
    }
    return nil
}

https://www.php.cn/link/8642785813491d703d517ddd00944054

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer