reverse(12345)
// 54321
のように、numberが入ったらreverse値を返す関数を作ろう、という問題。ただし、
You should do this without converting the inputted number into a string.(入力された数値を文字列に変換せずに行う必要があります。)
とあるので、このtestにpassさせつつ、実装する必要があります。
筆者の回答
function reverse(n, c = 0) {
c = c * 10 + n % 10;
n = Math.floor(n / 10);
return (n ? reverse(n, c) : c);
}
// reverse(1234);
// -> 4321
1回目cは、0 * 10 + 4(4は1234を10で割ったあまり) -> 4
その後、Math.floor(n/10)で、整数を維持したまま、桁数を減らす(1234 -> 123)
2回目cは、4 * 10 + 3(3は123を10で割ったあまり) -> 43
その後、Math.floor(n/10)で、整数を維持したまま、桁数を減らす(123 -> 12)
3回目cは、43 * 10 + 2(2は12を10で割ったあまり) -> 432
その後、Math.floor(n/10)で、整数を維持したまま、桁数を減らす(12 -> 1)
4回目cは、432 * 10 + 1(2は12を10で割ったあまり) -> 4321
その後、Math.floor(n/10)で、整数を維持したまま、桁数を減らす(1 -> 0)
5回目cは、4321 * 10 + 0(0は1を10で割ったあまり) -> 4321
その後、Math.floor(n/10)で、整数を維持したまま、桁数を減らす(0 -> 0)
JavaScriptで、0はfalse扱いなので、ここで再帰関数が終了して、
return (n ? reverse(n, c) : c); で、4321が返るようにしてます。再帰関数をわざわざ使う必要はないのですが、せっかくなので使用しました。ベストプラクティスは、whileで回していました。
その他の回答
アンサーの中でも「なにこれ?」となったのが、この回答でした。
const reverse = n => +([] + n).split([]+[]).reverse().join([]+[]);
⓪最初の+演算子は、数値変換するために使われるものです。
①([] + n)ですが
//コンソールログ
n=11
// 11
console.log([]+n === 11);
// false
console.log([]+n === '11');
// true
このように、([] とか "" + 数値) === 数字) となります。今回なら、n=4321であれば
([] + 4321)
// '4321'
となります。
②split([]+[])ですが
//コンソールログ
console.log('123'.split([]));
// ['1', '2', '3']
となります。ここのsplit([])は、split(”)と同義なのですが、split(”)で指定してしまうと、
You should do this without converting the inputted number into a string.(入力された数値を文字列に変換せずに行う必要があります。)
こちらのtestに引っ掛かるため、裏技みたいな形で上手く抜けれるんだなぁーと感心しました。
ただ、split([]+[])と2回[]を書く必要があるかな?と思ったのですが、知見がある方、是非ここの理由を伺いたいです。
この+([]+[+[]])みたいな可読性の無い処理に対する説明がありましたので、興味のある方は一読してみたら面白いと思います。