😀

golangでstringをsliceのように扱う

2022/08/19に公開2

記事を書いたきっかけ

https://leetcode.com/problems/valid-anagram をGolangで解いていました。
こちらを特にあたってstingを一旦sliceに変えて行おうとしたのですが、sliceに変えなくてもfor文で回せることを知ったので、こちらをまとめようと思います。

stringをsliceのように扱う方法

最初におこなっていたこと

まずはstringをsliceに置き換えたかったので

// ex) s = "anagram"
tmpS := strings.Split(s, "")
fmt.Println(tmpS)
// output 
// [a n a g r a m]

ただ、Discussにはstringをsliceに置き換えずに作業を進めているものがありました。
https://leetcode.com/problems/valid-anagram/discuss/2391924/GOLANG-16ms-FASTER-THAN-20

*下記はLeetCodeに関係なくPlayGroundでstringをそのまま使えすことを著したものです。

	hoge := "hogehogehoge"
	tmpHoge := []byte{}
	for i := range hoge {
		tmpHoge = append(tmpHoge, hoge[i])
	}
	fmt.Println(tmpHoge)
	
	// output
	[104 111 103 101 104 111 103 101 104 111 103 101]

こちらではbyte型で変えてくるのでint型と間違えないように注意が必要ですが、わざわざsliceに変換しなくても良い方法を知りました。

追記

https://zenn.dev/nobonobo sanからコメントをいただいたのでその部分を追記させていただきます。
上のやり方ではhogeからbyteの値をとっていますが、hogeをfor文で回した際のiはインクリメント順にならない可能性があるため、[]byte(hoge)でbyteスライスにキャストした方が好ましいとのことです。
また、キャストする際はbyteよりもruneの方が良さそう

	hoge := "ほげほげほげ"
	runeHoge := []rune(hoge)
	byteHoge := []byte(hoge)
	fmt.Println(byteHoge)
	fmt.Println(runeHoge)
	
	// output
	[227 129 187 227 129 146 227 129 187 227 129 146 227 129 187 227 129 146]
                [12411 12370 12411 12370 12411 12370]

正直学習不足でruneとbyteの違いはわかっていなくて詳しく説明できないです。すみません。
runeでキャストするとstringはcode pointに変換されるよう。
stringからbyte, runeのキャストはこちらの記事がおすすめです。
https://qiita.com/seihmd/items/4a878e7fa340d7963fee

まとめ

これからもLeetCodeをときながら、知らなかったこと、知ってよかったことをまとめたいです。
また、LeetCodeならではの普段API開発で使わないようなこともめげずに学習したいです。

Discussion

NoboNoboNoboNobo

byteスライスへの変換はキャストでできます。例:[]byte(hoge)

しかも例示コードではiはインクリメント順にならない状況があり得ます。考慮する必要があるかは問題によりますが、hoge文字列にアスキーではない文字が混じった場合に起こります。

以下のようにruneスライスにキャストするとよいと思います。
[]rune(hoge)

これなら文字数とインデックスが一致してアスキーじゃない文字が混じっても大丈夫です。

takotakotakotako

コメントありがとうございます。
指摘していただいた部分を修整させていただきたいと思います!