paizaの「整数と文字列を半角 + 改行区切りで入力 2 JavaScript編(paizaランク C 相当)」に挑戦しました。
今回は、
- 1行目:4つの整数が半角スペース区切り
- 2行目:文字列
- 整数にはそれぞれ
+1 - 5行に分けて出力
という問題です。
問題
4つの整数 a、b、c、d と文字列 S が与えられます。
a + 1、b + 1、c + 1、d + 1、S を改行区切りで出力します。
入力例
1 2 3 4
paiza
出力例
2
3
4
5
paiza
最初に書いたコード
process.stdin.resume();
process.stdin.setEncoding("utf8");
var lines = [];
var reader = require("readline").createInterface({
input: process.stdin,
output: process.stdout,
});
reader.on("line", (line) => {
lines.push(line);
});
reader.on("close", () => {
const input1 = lines[0].split(" ");
const input2 = lines[1].split(" ");
const a = Number(input1[0]);
const b = Number(input1[1]);
const c = Number(input1[2]);
const d = Number(input1[3]);
const S = input2[0];
console.log(a + 1);
console.log(b + 1);
console.log(c + 1);
console.log(d + 1);
console.log(S);
});
このコードでも正しく出力できます。
lines には何が入っている?
入力が、
1 2 3 4
paiza
だった場合、lines には行ごとに文字列が入ります。
lines[0] // "1 2 3 4"
lines[1] // "paiza"
つまり、
-
lines[0]→ 1行目 -
lines[1]→ 2行目
です。
split(" ") で半角スペースごとに分ける
1行目には4つの数字が半角スペース区切りで入っています。
const input1 = lines[0].split(" ");
これによって、
["1", "2", "3", "4"]
という配列になります。
そのため、
input1[0] // "1"
input1[1] // "2"
input1[2] // "3"
input1[3] // "4"
のように取り出せます。
Number() が必要な理由
split() で分けた値は、数字に見えても文字列です。
例えば、
input1[0]
の中身は数値の 1 ではなく、
"1"
という文字列です。
そこで、
const a = Number(input1[0]);
として数値に変換しています。
こうすることで、
a + 1
という計算ができます。
2行目は split() しなくてもよかった
最初は、
const input2 = lines[1].split(" ");
const S = input2[0];
と書きました。
ただし今回の S は半角スペースを含まない1つの文字列なので、
const S = lines[1];
だけでOKです。
つまり、少しシンプルにできます。
reader.on("close", () => {
const input1 = lines[0].split(" ");
const a = Number(input1[0]);
const b = Number(input1[1]);
const c = Number(input1[2]);
const d = Number(input1[3]);
const S = lines[1];
console.log(a + 1);
console.log(b + 1);
console.log(c + 1);
console.log(d + 1);
console.log(S);
});
さらにコンパクトに書く
今回は4つすべて整数なので、.map(Number) を使うと一気に数値へ変換できます。
const [a, b, c, d] = lines[0].split(" ").map(Number);
これだけで、
const a = Number(input1[0]);
const b = Number(input1[1]);
const c = Number(input1[2]);
const d = Number(input1[3]);
と同じような処理ができます。
コンパクト版
process.stdin.resume();
process.stdin.setEncoding("utf8");
var lines = [];
var reader = require("readline").createInterface({
input: process.stdin,
output: process.stdout,
});
reader.on("line", (line) => {
lines.push(line);
});
reader.on("close", () => {
const [a, b, c, d] = lines[0].split(" ").map(Number);
console.log(a + 1);
console.log(b + 1);
console.log(c + 1);
console.log(d + 1);
console.log(lines[1]);
});
かなりスッキリしました。
.map(Number) とは?
まず、
lines[0].split(" ")
によって、
["1", "2", "3", "4"]
になります。
さらに、
.map(Number)
をつけると、それぞれに Number() が実行されます。
[1, 2, 3, 4]
になります。
イメージとしては、
Number("1");
Number("2");
Number("3");
Number("4");
を全部まとめてやってくれている感じです。
[a, b, c, d] とは?
const [a, b, c, d] = [1, 2, 3, 4];
と書くと、
a // 1
b // 2
c // 3
d // 4
のように、配列の中身を順番に変数へ入れることができます。
これは「分割代入」と呼ばれる書き方です。
今回の場合、
const [a, b, c, d] = lines[0].split(" ").map(Number);
とすることで、
- 半角スペースで分割
- 数値に変換
-
a、b、c、dに代入
を1行で行っています。
console.log() を1回にすることもできる
さらに、
console.log(
[a + 1, b + 1, c + 1, d + 1, lines[1]].join("\n")
);
と書くこともできます。
reader.on("close", () => {
const [a, b, c, d] = lines[0].split(" ").map(Number);
console.log(
[a + 1, b + 1, c + 1, d + 1, lines[1]].join("\n")
);
});
.join("\n") は、配列の要素を改行でつなげるという意味です。
ただ、学習中の段階では、
console.log(a + 1);
console.log(b + 1);
console.log(c + 1);
console.log(d + 1);
console.log(lines[1]);
のように1つずつ書いた方が処理を追いやすいと感じました。
注意:console.log(a, b) は改行にならない
例えば、
console.log(a + 1, b + 1);
とすると、
2 3
のように半角スペース区切りで出力されます。
今回必要なのは、
2
3
という改行区切りです。
そのため、
console.log(a + 1);
console.log(b + 1);
と分けるか、
.join("\n")
を使う必要があります。
今回学んだこと
改行ごとの入力
lines[0]
lines[1]
で各行を取得できます。
半角スペースで分ける
split(" ")
文字列を数値に変換する
Number()
配列のすべての要素を数値に変換する
.map(Number)
配列の値をまとめて変数に入れる
const [a, b, c, d] = ...
改行区切りでまとめる
.join("\n")
まとめ
今回特に重要だったのは、
const [a, b, c, d] = lines[0].split(" ").map(Number);
という書き方でした。
最初は、
const a = Number(input1[0]);
const b = Number(input1[1]);
const c = Number(input1[2]);
const d = Number(input1[3]);
と1つずつ書いた方が理解しやすかったですが、処理が理解できたら .map(Number) と分割代入を使うことで、かなりコンパクトに書けることが分かりました。
まずは長くても自分で処理を理解できるコードを書いて、あとから「ここは短くできるかな?」と考えていくのも良さそうです。