つくる: 検索と集計
スライスとマップを組み合わせる
第5章の内容を全部使います。
プレーンテキスト
スライス 一覧を持つ
append 条件に合うものを集める
range 走査する
マップ カテゴリごとに数える
カンマok キーの有無を見分ける作るのは、キーワードで絞り込んでから集計する処理です。
プレーンテキスト
該当2件 合計2000円 最多カテゴリは本(2件)2つの役割を1つの for で
絞り込みと集計を、別々の for で書くこともできます。
Go
// 絞り込む
for i, name := range names { ... }
// 集計する
for _, price := range matched { ... }1回で済ませることもできます。
Go
for i, name := range names {
if 該当しない { continue }
total += prices[i]
counts[categories[i]]++
}どちらでも構いません。 分けたほうが1つ1つは読みやすく、まとめたほうが回る回数は減ります。この規模ならどちらでも差は出ないので、読みやすいと感じるほうを選んでください。
キーワードの一致
完全一致で判定します。商品名がキーワードと同じかどうかだけを見ます。
部分一致にすると strings.Contains が要りますが、この章では扱っていません。実務では部分一致のほうが多いので、第8章の検索APIで改めて出てきます。
キーワードが空文字のときは、すべてを対象にしてください。絞り込み無しの一覧、という意味になります。
最多カテゴリの求め方
マップを range で回して、いちばん大きいものを探します。
Go
maxCategory := ""
maxCount := 0
for category, count := range counts {
if count > maxCount {
maxCategory = category
maxCount = count
}
}ここで注意があります。マップを回す順番は毎回変わります。 同じ件数のカテゴリが2つあると、どちらが選ばれるか決まりません。
テストではその状況を作らないようにしてありますが、実際のコードでは同数のときの決め方を自分で決める必要があります。順番に頼れないというマップの性質が、こういう形で表に出てきます。
順番に作る
プレーンテキスト
1. 全件を集計する(絞り込み無し)
2. キーワードで絞る
3. カテゴリを数える
4. 最多を探す
5. 該当0件のときを分ける要件
- 商品名がキーワードと完全一致するものを集める
- キーワードが空文字のときはすべてを対象にする
該当N件 合計M円 最多カテゴリはC(K件)の形を返す- 該当が0件なら
該当なしを返す - カテゴリの集計にはマップを使う
入出力例
searchSummary(["きのこ図鑑","中古スマホ","古い辞書"], [1200,24800,800], ["本","家電","本"], "きのこ図鑑") → "該当1件 合計1200円 最多カテゴリは本(1件)"
searchSummary(["きのこ図鑑","古い辞書"], [1200,800], ["本","本"], "") → "該当2件 合計2000円 最多カテゴリは本(2件)"
searchSummary(["きのこ図鑑"], [1200], ["本"], "謎の箱") → "該当なし"
searchSummary(["A","B","C"], [100,200,300], ["家電","家電","本"], "") → "該当3件 合計600円 最多カテゴリは家電(2件)"ヒント
編集 ゆめさく編集部