こちらが気になったので色々と
投票とってみるか。
— いわた (@wonderful_panda) 2021年6月21日
「与えられた文字列をカンマでsplitした結果を配列で返す」というメソッドがあるとして、空文字列を指定した結果は
話の前後の事から多分この日に話題に上がったCSVの件からかと思いますが、なんでCSVなんて話題に上がるのかなとか思ってたのですが、そういえば数日前にCSVをパースするツールを発表した方がいたなぁって。
あぁ、、CSVなんてあんなもん業務でパースするにしても項目はダブルクオートする、値にカンマは入らない、改行なんてもってのほか、、、とか色々と制限を付けた上で仕事を進めるようなもんで(それでも想定外の値が入ってきて歯ぎしりするわけです。エクセルだと?今エクセルで出力したって言った?みたいな・・・)ましてや汎用的なCSVツールなんて作る気力は無いなぁ、、、とか思っていたわけです。ライブラリがあるならそちらを使うよねとか。
でもこういう誰もやんないような所で提供するのが大事なのだろうなぁとか色々思いながら発表した方にはただ凄いなぁという感想だったのです。
その中で興味があったのが上記のアンケート。
例えばCSVを読み込んで返すようなメソッドとかそういうのがここでは想定されているのかなとか。その中で読み込んだ1行をカンマでパースした場合に空文字だった場合どうなるか?という問題かと。
CSVの1行が空文字だったとしてその行をどういう仕様とするかはその業務により異なるので、仕様によりとしか言えなくなるのですが、自分が汎用的なものを作るとしたらこの場合は0件の配列を返すが自然ではないかと。
ツイ元の方としては結果を受けて以外だったというのが感想みたいで、わずかに0件の配列を返す派が優勢だったみたいですね。色々とリプとかを見てると1件以外ありえないだろうとか強めの意見が散見されて、、い、、いやぁ、、0件は変か?とか思いながら読んでましたが。
正直CSVの1行でもいいけど空文字送って1件帰ってきたら使いづらくね?って思ってたのですがその疑問に自分にリプをくださったのがこの方で。
あり得ないとまでは言わないですけど 1 派です。どう扱うのかの答えになっているのかはわからないですけど、ぼくは
— bouzuya (@bouzuya) 2021年6月22日
"abc".split(",") == ["abc"] になってほしくて、区切り文字がマッチしない場合に元の文字列が残るのであれば "".split(",") == [""] が一貫しているように思いました。
なるほどそれもそうだよなぁと。1件返ってきてもなんらおかしくない。
議論の中であぁなるほどって思わされたのがこちら。
「与えられた文字列をカンマでsplitした結果を配列で返す」という仕様だけに従うなら0になることはないよね。空文字列とかの条件でもう一つ追加仕様が入ってることになる。 https://t.co/3ZXHCMeQGn
— KOIZUKA, Akihiko (@koizuka) 2021年6月22日
自分は初めの設問から、与えられたCSVのレコードを返す際に使う側が利用しやすい形態は何か?(俺仕様と言ってもいい)を追加した上で設問に答えていたのだなと。
で、ここで自分はこのツイートを読んで重大な誤読?をしていたことに気づくのです。
「長さ0の文字列の配列」と読み間違えた人が仮に400人いたとしても得票率4:6なんですよね。それでもけっこう意外。
— いわた (@wonderful_panda) 2021年6月22日
たしかに [] [""] って書いたほうがよかったかなとは思いましたが。 https://t.co/QzUiZZLTz8
空文字とは、、、色々ツイを見てるとこういうケースを言ってる方がいました。
- ”” 長さ0の文字列
- "," 内容が長さ0の文字列が入った文字列
- " " スペース
- [""] 長さ0の文字列の配列
- いろいろ
自分は空文字って1の長さ0の文字列なのかなと思ってました。なのでCSVレコードとしては何も返らない方が後続処理としては自然かなと。でもJavaで "".split(",") を試したら1件なんですよね。こういう事からも自分は設問に対し、言語から離れて仕様を追加して解答している事が分かるのです。
ただ、2のケースは2件返ってほしいよねぇとか3のケースは当然1件とか自分の頭の仕様がなんだか破綻してるのに気づくのであった。(おわり)
ちなみにJava(11.0.1 2018-10-16 LTS)で色々ためしたら以下の結果でした。split()の第二引数により変わりますがとりあえず設問では指定が無かったので指定なしで。
ケース | 結果 | 備考 |
---|---|---|
”” | 1件 | 長さ0の文字列 |
” ” | 1件 | 長さ0の文字列 |
"," | 0件 | 長さ0を含む文字列 |
" , " | 2件 | スペースのカンマ区切り |
" ," | 1件 | 第二レコードが長さ0の文字列 |
", " | 2件 | 第一レコードが長さ0の文字列 |
コード
public class Test {
public static void main(String[] args) {
System.out.println("".split(","));
}
}