概要
paizaやAtCoderなどの競技プログラミングの問題から与えられる改行やカンマ区切りのデータを簡単に取得できる関数を作成しました。
この関数では単一行や複数行の半角/全角スペース、タブ、カンマ、改行が混在した文字列を配列に変換します。
GitHub:splitTokens — 汎用入力パーサ
Python版はこちら
特徴
- 半角/全角スペース、タブ、カンマ、改行で分割
- 文字列を配列に変換
- 単一行(単一値):1 → [ 1 ]
- 単一行(複数値):1 2 3 → [ 1, 2, 3 ]
- 複数行(複数値):1 2 3\n4 5 6 → [[ 1, 2, 3 ], [ 4, 5, 6 ]]
- 数値文字列は Number 型に変換
-
注意:
001のようなゼロ埋め数値文字は1となる -
注意:
+1のような符号付数値文字は1となる
-
注意:
使用例1:
const input = splitTokens(require('fs').readFileSync(0, 'utf8'));
console.log(input);
// 変換関数
function splitTokens(input) {
const normalized = normalizeInput(input);
const isSingleLine = !normalized.includes('\n');
// 単一行か複数行で処理を分岐
return isSingleLine ? parseSingleLine(normalized) : parseMultiLine(normalized);
}
// 入力文字列を正規化
function normalizeInput(str) {
return str
.replace(/\r\n?/g, '\n') // 改行統一
.replace(/\t/g, ' ') // タブ → 半角スペース
.replace(/\u3000/g, ' ') // 全角スペース → 半角スペース
.replace(/,/g, ' ') // カンマ → 半角スペース
.trim(); // 前後空白除去
}
// 一行の文字列を一次元配列に変換
function parseSingleLine(str) {
return str
.split(/ +/) // 半角スペースで分割
.filter(s => s.trim() !== '') // 空要素削除
.map((s) => /^[-+]?\d*\.?\d+$/.test(s) ? Number(s) : s); // 数値文字列を数値に変換
}
// 複数行の文字列を二次元配列に変換
function parseMultiLine(str) {
return str
.split('\n')
.filter(s => s.trim() !== '') // 空要素削除
.map(parseSingleLine);
}
使用例2:parseMultiLineで処理しアンラップ
splitTokensはこのように書くこともできます。
処理フローを一本化し、単一行なら一次元配列にアンラップする簡潔形です。
function splitTokens(input) {
const normalized = normalizeInput(input);
const rows = parseMultiLine(normalized);
return rows.length === 1 ? rows[0] : rows; // 単一行ならアンラップ
}
仕様
返却形式
- 単一行入力 → 一次元配列に変換
- 複数行入力 → 二次元配列に変換
- 数値文字列 → Number型に変換
変換例
| 入力 | 出力例 | 出力型 | 備考 |
|---|---|---|---|
a |
['a'] |
string[] | 単一文字列 |
1 |
[1] |
number[] | 単一整数 |
a b c |
['a','b','c'] |
string[] | 半角スペース区切り |
1,2,3 |
[1,2,3] |
number[] | カンマ区切り |
a,b,c\nd,e,f |
[['a','b','c'],['d','e','f']] |
string[][] | 複数行 |
1 2 3\n4 5 6 |
[[1,2,3],[4,5,6]] |
number[][] | 複数行整数 |
-1 -2 -3 |
[-1,-2,-3] |
number[] | 負の整数 |
10 apple 20 |
[10,'apple',20] |
(number|string)[] | 数値と文字列混在 |