Maison >développement back-end >Golang >Comment puis-je améliorer cette logique d'imbrication pour la faire fonctionner correctement et améliorer les performances

Comment puis-je améliorer cette logique d'imbrication pour la faire fonctionner correctement et améliorer les performances

王林
王林avant
2024-02-08 23:24:09660parcourir

Comment puis-je améliorer cette logique dimbrication pour la faire fonctionner correctement et améliorer les performances

Éditeur PHP Yuzai, vous avez peut-être rencontré des problèmes de logique imbriquée lors de l'écriture de code, entraînant un dysfonctionnement du code ou des performances médiocres. Pour améliorer ce problème, il y a plusieurs points clés à considérer. Tout d’abord, vous pouvez revoir votre structure logique pour voir si vous pouvez simplifier ou restructurer votre code afin de réduire le niveau d’imbrication. Deuxièmement, vous pouvez envisager d'utiliser des structures de données et des algorithmes appropriés pour optimiser votre code. Assurez-vous également que votre code ne duplique pas de calculs ou d'opérations redondantes pour améliorer les performances. Enfin, effectuez les tests et le débogage appropriés pour vous assurer que votre code fonctionne correctement dans diverses circonstances. Grâce à ces méthodes, vous pouvez améliorer la logique imbriquée et améliorer les performances de votre code.

Contenu des questions

J'ai une base de données contenant des commentaires, chaque commentaire a un identifiant et un identifiant parent. Le but est simplement de placer chaque commentaire avec un identifiant parent sous son commentaire parent de manière efficace.

J'ai initialement utilisé une fonction récursive pour rechercher l'annotation parent dans le tableau arranged, mais les performances étaient terribles. J'ai refactorisé pour utiliser des pointeurs pour suivre le parent, ce qui fonctionne presque parfaitement, mais il semble que le dernier commentaire à traiter soit toujours exclu de la sortie.

Dans l'exemple ci-dessous, "commentaire 1" doit être un enfant du "commentaire 11", mais il n'est pas du tout inclus dans la sortie.

package main

import (
  "encoding/json"
  "fmt"
)

// Comment from Database
type Comment struct {
  ID       string `json:"id""`
  ParentID string `json:"pid"`
  Text     string `json:"text"`
}

// NestedComment output
type NestedComment struct {
  Comment
  Children []NestedComment `json:"children,omitempty"`
}

func main() {
  // Some comment data from DB
  jsondata := `[{"id":"f1c3a838-f4b4-4ebd-bb1b-d3e4c0dce27d","pid":"6a162b3f-9341-46e9-95f7-dedc6cd06868","text":"comment 1"},{"id":"131cf4bb-1971-43a2-992f-2cbb042a4184","pid":"","text":"comment 2"},{"id":"4c93a789-ecab-4173-954c-b039cd3a9e17","pid":"131cf4bb-1971-43a2-992f-2cbb042a4184","text":"comment 3"},{"id":"c7974b6d-67e1-47d0-84fa-c78d51682df2","pid":"131cf4bb-1971-43a2-992f-2cbb042a4184","text":"comment 4"},{"id":"386c4439-4596-47c1-99bf-cb479055fe5a","pid":"","text":"comment 5"},{"id":"5ef0816e-ea13-4a7e-8009-e67ee08ef906","pid":"386c4439-4596-47c1-99bf-cb479055fe5a","text":"comment 6"},{"id":"96b0a536-602b-4f3f-a352-020f22cdfb18","pid":"","text":"comment 7"},{"id":"d0f11e98-deea-4fd5-becb-8f406ebcae83","pid":"96b0a536-602b-4f3f-a352-020f22cdfb18","text":"comment 8"},{"id":"bad87461-3cbf-4ecb-a8c7-36876b57d652","pid":"","text":"comment 9"},{"id":"e3ee6f90-495f-4348-9c29-bd6e15ec3b39","pid":"bad87461-3cbf-4ecb-a8c7-36876b57d652","text":"comment 10"},{"id":"6a162b3f-9341-46e9-95f7-dedc6cd06868","pid":"","text":"comment 11"},{"id":"041c7c2d-0688-491e-b6cd-899eac95bd3d","pid":"","text":"comment 12"},{"id":"5acdf3ff-345b-47a5-bd66-a6687a1441b7","pid":"041c7c2d-0688-491e-b6cd-899eac95bd3d","text":"comment 13"},{"id":"aaee2ae5-7e3a-4435-a094-83bf6b77abfb","pid":"","text":"comment 14"},{"id":"6108b28c-a7af-4c5a-a38c-c22db0d34b31","pid":"aaee2ae5-7e3a-4435-a094-83bf6b77abfb","text":"comment 15"},{"id":"1736393e-95b0-4f5d-a149-50fe52c28350","pid":"","text":"comment 16"},{"id":"b646f202-17aa-4af9-b8dc-c1d8ff3529ac","pid":"1736393e-95b0-4f5d-a149-50fe52c28350","text":"comment 17"},{"id":"a8827b1d-fdbc-41c2-bdb5-38e8b308dedc","pid":"b646f202-17aa-4af9-b8dc-c1d8ff3529ac","text":"comment 18"},{"id":"76e49597-6039-4cb5-a595-556ccc2e3c12","pid":"a8827b1d-fdbc-41c2-bdb5-38e8b308dedc","text":"comment 19"},{"id":"07dc4b90-65d3-4f75-8351-457305988235","pid":"76e49597-6039-4cb5-a595-556ccc2e3c12","text":"comment 20"},{"id":"2d4e838b-82df-4ca0-bf9b-f1dfb99d6763","pid":"07dc4b90-65d3-4f75-8351-457305988235","text":"comment 21"},{"id":"617c1760-0dca-409c-af2a-c614f0530e07","pid":"","text":"comment 22"},{"id":"712c0b7e-a9e4-40fd-ab78-c39b483b1435","pid":"617c1760-0dca-409c-af2a-c614f0530e07","text":"comment 23"},{"id":"e325094c-886e-42c9-bd59-fdd7a189b384","pid":"","text":"comment 24"},{"id":"f3b8b0f9-edef-4ee6-9555-42e8595f854c","pid":"e325094c-886e-42c9-bd59-fdd7a189b384","text":"comment 25"},{"id":"6e09a231-a2ee-4aa1-a898-57695e6fe153","pid":"","text":"comment 26"},{"id":"63e629d6-c0f9-4b36-ad96-e0c47cf8bb4e","pid":"6e09a231-a2ee-4aa1-a898-57695e6fe153","text":"comment 27"},{"id":"d7b698f1-8757-46db-a6e6-5141a481b42b","pid":"","text":"comment 28"},{"id":"a7e3d522-553c-44f1-befa-047bd94f0e59","pid":"","text":"comment 29"},{"id":"fe78ce24-c2c8-4d00-b96d-8b8be9ce0f06","pid":"","text":"comment 30"},{"id":"fabdccb5-a024-4476-bd51-7d55fb685c42","pid":"","text":"comment 31"},{"id":"608d0693-6e43-46a0-9e54-107da6adb109","pid":"fabdccb5-a024-4476-bd51-7d55fb685c42","text":"comment 32"}]`

  var comments []Comment

  err := json.Unmarshal([]byte(jsondata), &comments)
  if err != nil {
    panic(err)
  }

  arranged := ArrangeComments(comments, len(comments))

  arrangedjson, _ := json.MarshalIndent(arranged, "", "  ")

  fmt.Println(string(arrangedjson))
  fmt.Println("comments", len(comments), "arranged", recursiveCount(arranged))
}

func recursiveCount(arranged []NestedComment) int {
    count := len(arranged)
    for _, item := range arranged {
        count += recursiveCount(item.Children)
    }
    return count
}

// Nesting function -------------------------------------------------------------------------

func ArrangeComments(queue []Comment, count int) []NestedComment {
  var arranged []NestedComment

  // using pointers over a recursive search
  var refs []*NestedComment

  // some comments are orphaned, se we need a bail out
  tries := 0
  maxTries := 5
  prevPlacedLen := 0

  // IDs of placed comments
  var placed []string

  // while count is greater then length of placed
countloop:
  for count > len(placed) {
    // loop through queue
  queueloop:
    for _, item := range queue {

      // skip if already placed
      if len(placed) > 0 {
        for _, id := range placed {
          if id == item.ID {
            continue queueloop
          }
        }
      }

      // if parent is nil, add to arranged
      if item.ParentID == "" {
        arranged = append(arranged, NestedComment{
          Comment: item,
        })
        refs = append(refs, &arranged[len(arranged)-1])
        placed = append(placed, item.ID)
      } else {
        // if parent is not nil, loop through refs and add to children
      refloop:
        for _, ref := range refs {
          if ref.ID == item.ParentID {
            ref.Children = append(ref.Children, NestedComment{Comment: item})
            refs = append(refs, &ref.Children[len(ref.Children)-1])
            placed = append(placed, item.ID)
            break refloop
          }
        }
      }
    }

    // if no comments were placed, bail out after x tries
    if len(placed) == prevPlacedLen {
      if tries >= maxTries {
        break countloop
      }
      tries++
      break
    }

    prevPlacedLen = len(placed)
  }

  return arranged
}

Mise à jour ; cela m'a rapproché, mais je n'ai pas réussi à imbriquer des commentaires plus profonds. Bizarrement, il produit un résultat différent à chaque exécution :

func ArrangeComments(comments []Comment) []NestedComment {
    // Map to hold references to NestedComment by their ID
    queue := make(map[string]*NestedComment)

    // Result slice
    var result []NestedComment

    // First, create all NestedComments and store references in the map
    for _, comment := range comments {
        nc := &NestedComment{Comment: comment}
        queue[comment.ID] = nc
    }

    // Second, loop through the map and add children to their parents
    for _, comment := range queue {
        if comment.ParentID != "" {
            parent := queue[comment.Comment.ParentID]
            if parent != nil {
                parent.Children = append(parent.Children, *comment)
            }
        }
    }

    // Third, loop through the map and add all root comments to the result slice
    for _, comment := range queue {
        if comment.ParentID == "" {
            result = append(result, *comment)
        }
    }

    return result
}

Mise à jour ; j'ai rapidement écrit une implémentation JavaScript qui produit les résultats corrects avec les mêmes exemples de données, mais je n'arrive pas à comprendre pourquoi ce code JS fonctionne et pas le code Go.

const datajson = `[{"id":"f1c3a838-f4b4-4ebd-bb1b-d3e4c0dce27d","pid":"6a162b3f-9341-46e9-95f7-dedc6cd06868","text":"comment 1"},{"id":"131cf4bb-1971-43a2-992f-2cbb042a4184","pid":"","text":"comment 2"},{"id":"4c93a789-ecab-4173-954c-b039cd3a9e17","pid":"131cf4bb-1971-43a2-992f-2cbb042a4184","text":"comment 3"},{"id":"c7974b6d-67e1-47d0-84fa-c78d51682df2","pid":"131cf4bb-1971-43a2-992f-2cbb042a4184","text":"comment 4"},{"id":"386c4439-4596-47c1-99bf-cb479055fe5a","pid":"","text":"comment 5"},{"id":"5ef0816e-ea13-4a7e-8009-e67ee08ef906","pid":"386c4439-4596-47c1-99bf-cb479055fe5a","text":"comment 6"},{"id":"96b0a536-602b-4f3f-a352-020f22cdfb18","pid":"","text":"comment 7"},{"id":"d0f11e98-deea-4fd5-becb-8f406ebcae83","pid":"96b0a536-602b-4f3f-a352-020f22cdfb18","text":"comment 8"},{"id":"bad87461-3cbf-4ecb-a8c7-36876b57d652","pid":"","text":"comment 9"},{"id":"e3ee6f90-495f-4348-9c29-bd6e15ec3b39","pid":"bad87461-3cbf-4ecb-a8c7-36876b57d652","text":"comment 10"},{"id":"6a162b3f-9341-46e9-95f7-dedc6cd06868","pid":"","text":"comment 11"},{"id":"041c7c2d-0688-491e-b6cd-899eac95bd3d","pid":"","text":"comment 12"},{"id":"5acdf3ff-345b-47a5-bd66-a6687a1441b7","pid":"041c7c2d-0688-491e-b6cd-899eac95bd3d","text":"comment 13"},{"id":"aaee2ae5-7e3a-4435-a094-83bf6b77abfb","pid":"","text":"comment 14"},{"id":"6108b28c-a7af-4c5a-a38c-c22db0d34b31","pid":"aaee2ae5-7e3a-4435-a094-83bf6b77abfb","text":"comment 15"},{"id":"1736393e-95b0-4f5d-a149-50fe52c28350","pid":"","text":"comment 16"},{"id":"b646f202-17aa-4af9-b8dc-c1d8ff3529ac","pid":"1736393e-95b0-4f5d-a149-50fe52c28350","text":"comment 17"},{"id":"a8827b1d-fdbc-41c2-bdb5-38e8b308dedc","pid":"b646f202-17aa-4af9-b8dc-c1d8ff3529ac","text":"comment 18"},{"id":"76e49597-6039-4cb5-a595-556ccc2e3c12","pid":"a8827b1d-fdbc-41c2-bdb5-38e8b308dedc","text":"comment 19"},{"id":"07dc4b90-65d3-4f75-8351-457305988235","pid":"76e49597-6039-4cb5-a595-556ccc2e3c12","text":"comment 20"},{"id":"2d4e838b-82df-4ca0-bf9b-f1dfb99d6763","pid":"07dc4b90-65d3-4f75-8351-457305988235","text":"comment 21"},{"id":"617c1760-0dca-409c-af2a-c614f0530e07","pid":"","text":"comment 22"},{"id":"712c0b7e-a9e4-40fd-ab78-c39b483b1435","pid":"617c1760-0dca-409c-af2a-c614f0530e07","text":"comment 23"},{"id":"e325094c-886e-42c9-bd59-fdd7a189b384","pid":"","text":"comment 24"},{"id":"f3b8b0f9-edef-4ee6-9555-42e8595f854c","pid":"e325094c-886e-42c9-bd59-fdd7a189b384","text":"comment 25"},{"id":"6e09a231-a2ee-4aa1-a898-57695e6fe153","pid":"","text":"comment 26"},{"id":"63e629d6-c0f9-4b36-ad96-e0c47cf8bb4e","pid":"6e09a231-a2ee-4aa1-a898-57695e6fe153","text":"comment 27"},{"id":"d7b698f1-8757-46db-a6e6-5141a481b42b","pid":"","text":"comment 28"},{"id":"a7e3d522-553c-44f1-befa-047bd94f0e59","pid":"","text":"comment 29"},{"id":"fe78ce24-c2c8-4d00-b96d-8b8be9ce0f06","pid":"","text":"comment 30"},{"id":"fabdccb5-a024-4476-bd51-7d55fb685c42","pid":"","text":"comment 31"},{"id":"608d0693-6e43-46a0-9e54-107da6adb109","pid":"fabdccb5-a024-4476-bd51-7d55fb685c42","text":"comment 32"}]`

const queue = JSON.parse(datajson)

const result = []

const queueMap = new Map(queue.map(item => [item.id, item]))

for (const item of queue) {
  if (item.pid !== '') {
    const parent = queueMap.get(item.pid)
    if (parent) {
      if (!parent.children) {
        parent.children = []
      }
      parent.children.push(item)
    }
  }
}

for (const [_, value] of queueMap) {
  if (value.pid === '') {
    result.push(value)
  }
}

function recursiveCount(res) {
  let count = res.length
  res.forEach(item => {
    if (item.children) {
      count += recursiveCount(item.children)
    }
  });
  return count
}


console.log(JSON.stringify(result, null, 2))
console.log("comments", queue.length, "arranged", recursiveCount(result))

Exemple Runnable Go : https://gist.github.com/dlford/9e66069cfc7fb9afc649c5e3dc650083

Exemple JS exécutable : https://gist.github.com/dlford/f6f4a383a99f65659895ed51d1a4b651

Sortie du code Go (voir le décompte en bas) : https://gist.github.com/dlford/302c4db939c21d15132848368caa01ec

Sortie du code JS (voir le nombre en bas) : https://gist.github.com/dlford/60ab49d0466c957c7745059022e27e09

Contournement

Le problème est que NestedComment 中的 Children doit également être stocké en tant que pointeur.

Exemple de travail :

package main

import (
    "encoding/json"
    "fmt"
)

// Comment from Database
type Comment struct {
    ID       string `json:"id"`
    ParentID string `json:"pid"`
    Text     string `json:"text"`
}

// NestedComment output
type NestedComment struct {
    Comment
    Children []*NestedComment `json:"children,omitempty"`
}

func main() {
    // Some comment data from DB
    jsondata := `[{"id":"f1c3a838-f4b4-4ebd-bb1b-d3e4c0dce27d","pid":"6a162b3f-9341-46e9-95f7-dedc6cd06868","text":"comment 1"},{"id":"131cf4bb-1971-43a2-992f-2cbb042a4184","pid":"","text":"comment 2"},{"id":"4c93a789-ecab-4173-954c-b039cd3a9e17","pid":"131cf4bb-1971-43a2-992f-2cbb042a4184","text":"comment 3"},{"id":"c7974b6d-67e1-47d0-84fa-c78d51682df2","pid":"131cf4bb-1971-43a2-992f-2cbb042a4184","text":"comment 4"},{"id":"386c4439-4596-47c1-99bf-cb479055fe5a","pid":"","text":"comment 5"},{"id":"5ef0816e-ea13-4a7e-8009-e67ee08ef906","pid":"386c4439-4596-47c1-99bf-cb479055fe5a","text":"comment 6"},{"id":"96b0a536-602b-4f3f-a352-020f22cdfb18","pid":"","text":"comment 7"},{"id":"d0f11e98-deea-4fd5-becb-8f406ebcae83","pid":"96b0a536-602b-4f3f-a352-020f22cdfb18","text":"comment 8"},{"id":"bad87461-3cbf-4ecb-a8c7-36876b57d652","pid":"","text":"comment 9"},{"id":"e3ee6f90-495f-4348-9c29-bd6e15ec3b39","pid":"bad87461-3cbf-4ecb-a8c7-36876b57d652","text":"comment 10"},{"id":"6a162b3f-9341-46e9-95f7-dedc6cd06868","pid":"","text":"comment 11"},{"id":"041c7c2d-0688-491e-b6cd-899eac95bd3d","pid":"","text":"comment 12"},{"id":"5acdf3ff-345b-47a5-bd66-a6687a1441b7","pid":"041c7c2d-0688-491e-b6cd-899eac95bd3d","text":"comment 13"},{"id":"aaee2ae5-7e3a-4435-a094-83bf6b77abfb","pid":"","text":"comment 14"},{"id":"6108b28c-a7af-4c5a-a38c-c22db0d34b31","pid":"aaee2ae5-7e3a-4435-a094-83bf6b77abfb","text":"comment 15"},{"id":"1736393e-95b0-4f5d-a149-50fe52c28350","pid":"","text":"comment 16"},{"id":"b646f202-17aa-4af9-b8dc-c1d8ff3529ac","pid":"1736393e-95b0-4f5d-a149-50fe52c28350","text":"comment 17"},{"id":"a8827b1d-fdbc-41c2-bdb5-38e8b308dedc","pid":"b646f202-17aa-4af9-b8dc-c1d8ff3529ac","text":"comment 18"},{"id":"76e49597-6039-4cb5-a595-556ccc2e3c12","pid":"a8827b1d-fdbc-41c2-bdb5-38e8b308dedc","text":"comment 19"},{"id":"07dc4b90-65d3-4f75-8351-457305988235","pid":"76e49597-6039-4cb5-a595-556ccc2e3c12","text":"comment 20"},{"id":"2d4e838b-82df-4ca0-bf9b-f1dfb99d6763","pid":"07dc4b90-65d3-4f75-8351-457305988235","text":"comment 21"},{"id":"617c1760-0dca-409c-af2a-c614f0530e07","pid":"","text":"comment 22"},{"id":"712c0b7e-a9e4-40fd-ab78-c39b483b1435","pid":"617c1760-0dca-409c-af2a-c614f0530e07","text":"comment 23"},{"id":"e325094c-886e-42c9-bd59-fdd7a189b384","pid":"","text":"comment 24"},{"id":"f3b8b0f9-edef-4ee6-9555-42e8595f854c","pid":"e325094c-886e-42c9-bd59-fdd7a189b384","text":"comment 25"},{"id":"6e09a231-a2ee-4aa1-a898-57695e6fe153","pid":"","text":"comment 26"},{"id":"63e629d6-c0f9-4b36-ad96-e0c47cf8bb4e","pid":"6e09a231-a2ee-4aa1-a898-57695e6fe153","text":"comment 27"},{"id":"d7b698f1-8757-46db-a6e6-5141a481b42b","pid":"","text":"comment 28"},{"id":"a7e3d522-553c-44f1-befa-047bd94f0e59","pid":"","text":"comment 29"},{"id":"fe78ce24-c2c8-4d00-b96d-8b8be9ce0f06","pid":"","text":"comment 30"},{"id":"fabdccb5-a024-4476-bd51-7d55fb685c42","pid":"","text":"comment 31"},{"id":"608d0693-6e43-46a0-9e54-107da6adb109","pid":"fabdccb5-a024-4476-bd51-7d55fb685c42","text":"comment 32"}]`

    var comments []Comment

    err := json.Unmarshal([]byte(jsondata), &comments)
    if err != nil {
        panic(err)
    }

    arranged := ArrangeComments(comments)

    arrangedjson, _ := json.MarshalIndent(arranged, "", "  ")

    fmt.Println(string(arrangedjson))
    fmt.Println("comments", len(comments), "arranged", recursiveCount(arranged))
}

func recursiveCount(arranged []*NestedComment) int {
    count := len(arranged)
    for _, item := range arranged {
        count += recursiveCount(item.Children)
    }
    return count
}

// Nesting function -------------------------------------------------------------------------

func ArrangeComments(comments []Comment) []*NestedComment {
    // Map to hold references to NestedComment by their ID
    queue := make(map[string]*NestedComment)

    // Result slice
    var result []*NestedComment

    // First, create all NestedComments and store references in the map
    for _, comment := range comments {
        nc := &NestedComment{Comment: comment}
        queue[comment.ID] = nc
    }

    // Second, loop through the map and add children to their parents
    for _, comment := range queue {
        if comment.ParentID != "" {
            parent := queue[comment.Comment.ParentID]
            if parent != nil {
                parent.Children = append(parent.Children, comment)
            }
        }
    }

    // Third, loop through the map and add all root comments to the result slice
    for _, comment := range queue {
        if comment.ParentID == "" {
            result = append(result, comment)
        }
    }

    return result
}

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