スライス
角括弧に数を書かない
Go
var prices []int // スライス
var prices [3]int // 配列見た目の違いは数字の有無だけですが、性質はまるで違います。
プレーンテキスト
配列 長さが型の一部。渡すとコピーされる
スライス 長さは型に含まれない。渡してもコピーされない実際の Go のコードで並びを扱うときは、ほぼ全部スライスです。
作り方
Go
prices := []int{1200, 24800, 999} // 値から作る
prices := make([]int, 3) // 長さ3で作る。中身はゼロ値
var prices []int // 空。ゼロ値は nil3つ目に注意してください。スライスのゼロ値は nil です。ただし nil のスライスにも len() は使えて、0 を返します。
Go
var prices []int
len(prices) // 0。panic にはならない空のスライスとして普通に扱えるので、nil かどうかを気にせず for で回せます。
中身は共有される
スライスの正体は、どこかにある配列を指す情報です。実際のデータは別の場所にあり、スライス自身は「どこから、いくつ分か」を持っているだけです。
そのため、渡しても中身はコピーされません。
Go
func discount(p []int) {
p[0] = 0
}
prices := []int{1200, 24800}
discount(prices)
fmt.Println(prices[0]) // 0。書き換わっている配列のときと結果が逆になります。渡した先で書き換えられるということです。
速いぶん、意図しない書き換えが起こりえます。関数に渡すときは、その関数が中身を変えるのかどうかを意識してください。
一部を切り出す
Go
prices := []int{1200, 24800, 999, 500}
prices[1:3] // [24800, 999]
prices[:2] // [1200, 24800]
prices[2:] // [999, 500][開始:終了] で切り出せます。開始は含み、終了は含みません。 [1:3] は添字 1 と 2 の2つです。
この範囲の書き方は、for i := 0; i < len(prices); i++ と同じ考え方です。終わりを含まないので、len をそのまま終了位置に書けます。
切り出したものは元と同じ場所を指しています。片方を書き換えると、もう片方にも影響します。ここは入門の範囲を超えるので、いまは「切り出してもコピーではない」とだけ覚えておいてください。
要件
- 先頭3件までを集計する
- 3件に満たないときは、あるだけを集計する
先頭N件 合計M円の形を返す- スライスの切り出し
prices[:n]を使う
入出力例
topThree([1200,24800,999,500,300]) → "先頭3件 合計26999円"
topThree([1000,2000,3000]) → "先頭3件 合計6000円"
topThree([1200,999]) → "先頭2件 合計2199円"
topThree([1200]) → "先頭1件 合計1200円"ヒント
編集 ゆめさく編集部