2017-10-18 8 views
3

J'apprends le golang. J'essaie de stocker un peu de données, que je vais ensuite envoyer au fichier. Quel serait l'équivalent golang de ce bloc python?golang équivalent à la liste des dicts pour stocker des données

(une liste de dicts)

friends = [ 
    { 
    "name":"James", 
    "age":44, 
    }, 
    { 
    "name":"Jane", 
    "age":47, 
    }, 
] 

Serait-il préférable d'utiliser une tranche de cartes ou une structure? Je veux être capable de filtrer les données (par exemple tous les amis de plus de 45 ans) et de trier les données (imaginons que j'ai plus de 12 enregistrements). puis imprimez-le à l'écran.

+4

La comparaison directe serait une tranche de cartes, mais sans réelle problème que nous ne pouvons pas dire, ce qui est mieux. – JimB

Répondre

3

Nombreux sont les cas où vous utilisez un dict en python, vous voulez un struct pour Go, pour obtenir une typage statique. Dans votre cas, cela ressemble à une tranche de struct pour moi:

type Friend struct{ 
    Name string `json:"name"` 
    Age int `json:"age"` 
} 

et vous pouvez linéariser/désérialiser à []*Person

2

équivalent de Puuhon de list est un slice, à la fois a la même sémantique et cas d'utilisation.

Mais que mettre dans une tranche? Cela dépend de vos dicts. Si ce sont les mêmes champs, je recommande d'utiliser struct s. Donnez-lui des champs comme ci-dessus. Parfois, vous devez stocker différentes clés et différentes valeurs de chaîne par exemple. Définir comme une chaîne de carte à chaîne:

map[string]string 

En dernier recours, il y a une possibilité de faire carte typée dynamiquement. Mais ce n'est pas pour l'abuser parce que vous perdez tous les avantages du typage statique. Le programme devient plus sujet aux erreurs et plus lent.

1

Étant donné que vos données d'échantillon semble être homogène (amis partagent leurs propriétés), vous pouvez utiliser un slice de struct s, comme si:

type Friend struct { 
    Name string 
    Age int 
} 

var friends []Friend = make([]Friend, 0) 

maintenant, nous allons dire que vous avez déjà ajouté des amis à cette tranche, vous pouvez filtrer ceux qui Age supérieur à un certain nombre:

func filterFriendsAboveAge(allFriends []Friend, minAge int) []Friend { 
    results := make([]Friend, 0) 
    for _, friend := range allFriends { 
     if friend.Age > minAge { 
      results = append(results, friend) 
     } 
    } 
    return results 
} 

S'il vous plaît noter que en appelant cette fonction, les valeurs ami dans la tranche de retour seront des copies de l'original. Si vous devez conserver l'identité, utilisez plutôt des pointeurs.

1

Voici un petit programme d'échantillonnage qui fait ce que vous voulez:

package main 

import (
    "fmt" 
    "sort" 
) 

type friend struct { 
    name string 
    age int 
} 

func main() { 
    friends := []friend{ 
     {"James", 44}, 
     {"Jane", 47}, 
     {"Bob", 30}, 
     {"Cesar", 90}, 
     {"John", 45}, 
    } 

    over45 := filterFriends(friends, func(f friend) bool { 
     return f.age > 45 
    }) 
    fmt.Println("over 45:", over45) 

    // note that sort.Sort will change the contents of the slice; if you want 
    // to keep the original order as well, you would first have to copy that 
    // slice and sort the copy 
    sort.Sort(byAge(friends)) 
    fmt.Println("sorted by age:", friends) 
} 

// filterFriends takes your slice and a predicate to filter by, then returns a 
// newly allocated list of friends that made it through the filter. 
func filterFriends(friends []friend, pred func(friend) bool) []friend { 
    var fit []friend 
    for _, f := range friends { 
     if pred(f) { 
      fit = append(fit, f) 
     } 
    } 
    return fit 
} 

// byAge implements the sort.Interface so we can pass it to sort.Sort. 
type byAge []friend 

func (f byAge) Len() int   { return len(f) } 
func (f byAge) Less(i, j int) bool { return f[i].age < f[j].age } 
func (f byAge) Swap(i, j int)  { f[i], f[j] = f[j], f[i] } 

la sortie du programme est:

over 45: [{Jane 47} {Cesar 90}] 
sorted by age: [{Bob 30} {James 44} {John 45} {Jane 47} {Cesar 90}]