🐭

【Go】構造体のスライスをフィールドの要素別にカウントする方法

2022/06/25に公開

表題のとおりです。
「1.構造体を使う方法」と「2.mapを使う方法」を書いています。
個人的には構造体のほうが扱いやすくて好きです。

ある集団について血液型別に集計する例を実装しました。

1. 構造体を使う方法

カウンターを作成して単純にインクリメントしていきます。

https://go.dev/play/p/bhNBDUkczYZ

// You can edit this code!
// Click here and start typing.
package main

import (
	"fmt"
	"math/rand"
	"time"
)

type Person struct {
	Id        int
	BloodType string
}

type Persons []Person

func generateDummys(size int) Persons {
	rand.Seed(time.Now().UnixNano())
	ps := make(Persons, 0, size)
	for i := 0; i < size; i++ {
		var p Person
		p.Id = i
		rd := rand.Intn(4)
		switch rd {
		case 0:
			p.BloodType = "A"
		case 1:
			p.BloodType = "B"
		case 2:
			p.BloodType = "AB"
		default:
			p.BloodType = "O"
		}
		ps = append(ps, p)
	}
	return ps
}

type TypeCounter struct {
	A  int
	B  int
	AB int
	O  int
}

func (ps Persons) count() TypeCounter {
	var counter TypeCounter
	for _, p := range ps {
		switch p.BloodType {
		case "A":
			counter.A++
		case "B":
			counter.B++
		case "AB":
			counter.AB++
		default:
			counter.O++
		}
	}
	return counter
}

func main() {
	ps := generateDummys(120)
	cnt := ps.count()
	fmt.Printf("Result %+v", cnt)
}

2. mapを使う方法

構造体を使う方法と似ているけど、mapを使う方法

// You can edit this code!
// Click here and start typing.
package main

import (
	"fmt"
	"math/rand"
	"time"
)

type Person struct {
	Id        int
	BloodType string
}

type Persons []Person

func generateDummys(size int) Persons {
	rand.Seed(time.Now().UnixNano())
	ps := make(Persons, 0, size)
	for i := 0; i < size; i++ {
		var p Person
		p.Id = i
		rd := rand.Intn(4)
		switch rd {
		case 0:
			p.BloodType = "A"
		case 1:
			p.BloodType = "B"
		case 2:
			p.BloodType = "AB"
		default:
			p.BloodType = "O"
		}
		ps = append(ps, p)
	}
	return ps
}

func main() {
	ps := generateDummys(120)
	bloodType := map[string]int{
		"A":  0,
		"B":  0,
		"AB": 0,
		"O":  0,
	}
	for _, p := range ps {
		switch p.BloodType {
		case "A":
			bloodType["A"]++
		case "B":
			bloodType["B"]++
		case "AB":
			bloodType["AB"]++
		default:
			bloodType["O"]++
		}
	}
	fmt.Printf("Result %+v", bloodType)
}

https://go.dev/play/p/p_mGx7k2iJl

Discussion