つくる: 検索と集計
スライスとマップを組み合わせる
第5章で学んだスライスの走査とマップの集計を組み合わせます。演習で書くのは、絞り込みと件数・合計・カテゴリ件数の更新だけです。初期値、最多カテゴリの探索、0件処理、表示はひな形に用意しています。
スライス 一覧を持つ
append 条件に合うものを集める
range 走査する
マップ カテゴリごとに数える
カンマok キーの有無を見分ける作るのは、キーワードで絞り込んでから集計する処理です。
該当2件 合計2000円 最多カテゴリは本(2件)2つの役割を1つの for で
条件に合わない要素を continue で飛ばすと、その後には対象だけが残ります。別の題材として、観測値のうち正の値だけを合計してみます。
Go
readings := []int{4, -1, 6}
sum := 0
for _, reading := range readings {
if reading <= 0 {
continue
}
sum += reading
}
// sum は 10continue は今の要素の残りの処理を飛ばし、次の要素へ進みます。1回の走査の中で、対象かどうかの判定と集計を行えます。
&& は「かつ」で、両方が真のときだけ真です。例えば temperature < 0 && raining は「気温が0未満で、雨も降っている」という条件です。演習では、空のキーワードを除外条件に含めないように考えてください。
キーワードの一致
完全一致で判定します。商品名がキーワードと同じかどうかだけを見ます。
部分一致にすると strings.Contains が要りますが、この章では扱っていません。実務では部分一致のほうが多いので、第8章の検索APIで改めて出てきます。
キーワードが空文字のときは、すべてを対象にしてください。絞り込み無しの一覧、という意味になります。
最多カテゴリの求め方
マップを range で回して、いちばん大きいものを探します。
別の題材では、チームごとの得票数から最多票を探せます。
Go
votes := map[string]int{"赤組": 5, "青組": 3}
winner := ""
largest := 0
for team, votesForTeam := range votes {
if votesForTeam > largest {
winner = team
largest = votesForTeam
}
}ここで注意があります。マップを回す順番は毎回変わります。 同じ件数のカテゴリが2つあると、どちらが選ばれるか決まりません。
テストではその状況を作らないようにしてありますが、実際のコードでは同数のときの決め方を自分で決める必要があります。順番に頼れないというマップの性質が、こういう形で表に出てきます。
演習で担当する部分
searchSummary の for の中を完成させます。まず対象外を飛ばし、残った商品の価格を合計へ足して、全体の件数とカテゴリの件数を増やします。マップは未登録のキーを読むと0になるので、カテゴリの更新にカンマokは要りません。
最多を探すコードと fmt.Sprintf による表示は、そのまま使ってください。fmt.Sprintf("残り%d分", 12) は 残り12分 という文字列を作る書き方です。
要件
- 商品名がキーワードと完全一致するものを集める
- キーワードが空文字のときはすべてを対象にする
該当N件 合計M円 最多カテゴリはC(K件)の形を返す- 該当が0件なら
該当なしを返す - カテゴリの集計にはマップを使う
- 3つの並びは同じ長さで、同じ添字は同じ商品を表す
- 最多カテゴリが同数になる入力は採点の対象外