JavaScript中級トレーニング10問(String編)
この前の記事(JavaScript 30-seconds-of-code String編)をベースにJavaScript問題集を作ってみました。
問題は全部で10問。正規表現をゴリゴリ使うのはなるべく避けてみました。個人的にはヒント見ずに(ググらずに)1時間で全部解けたらマスタークラスだと思います。
- isLowerCase
- reverseString
- truncateString
- mapString
- mask
- compactWhitespace
- palindrome
- capitalize
- byteSize
- pluralize
開発環境はブラウザとエディタで十分ですがCodeSandboxも便利です。
CodeSandboxをVanillaで起動してもらうとJavaScriptコードの勉強にちょうど良いです。
それでははりきってどうぞ。
1 isLowerCase
文字列が小文字か検証します。次の実行結果となるようにisLowerCase関数を定義してください。
isLowerCase('abc'); // true isLowerCase('a3@$'); // true isLowerCase('Ab4'); // false
isLowerCase関数を実装して、console.log(isLowerCase('abc')) でtrueが出力されればOKです。
ヒント
String.prototype.toLowerCase()を使って、与えられた文字列を小文字に変換し、元の文字列と等しいか比較します。
const isLowerCase = str => str === str.t__________();
2 reverseString
文字列を反転します。次の実行結果となるようにreverseString関数を定義してください。
reverseString('foobar'); // 'raboof'
ヒント
スプレッドオペレータ(...)とArray.prototype.reverse()を使って文字列内の文字の並びを逆順にしString.prototype.join('')によって文字を連結して文字列とします。
const reverseString = str => [...str].r______().j___('');
3 truncateString
指定したサイズで文字列を切り詰めます。次の実行結果となるようにtruncateString関数を定義してください。
truncateString('boomerang', 7); // 'boom...'
ヒント
文字列のサイズの上限を指定します。切り詰められた文字列の後部に'...'を連結して返します。
const truncateString = (str, num) => str.l_____ > num ? str.s____(0, num > 3 ? num - 3 : num) + '...' : str;
4 mapString
文字列に含まれる個々の文字に対して、指定されたコールバック関数を適用して、新たな文字列を生成します。次の実行結果となるようにmapString関数を定義してください。
mapString('lorem ipsum', c => c.toUpperCase()); // 'LOREM IPSUM'
ヒント
String.prototype.split('')とArray.prototype.map()を使って、コールバック関数(引数のfn)を文字列内の個々の文字に対して適用します。それからArray.prototype.join('')を使って文字配列を文字列として再結合します。コールバック関数は3つの引数(現在の文字、現在の文字のインデックス、mapString関数の引数に指定された文字列)を受け取ります。
const mapString = (str, fn) => str .s____('') .m__((c, i) => f_(c, i, str)) .j___('');
5 mask
文字列を指定されたマスク文字で置き換えます。ただし、文字列の後部については、引数のnumに指定された文字数分はマスクしません。次の実行結果となるようにmask関数を定義してください。
mask(1234567890); // '******7890' mask(1234567890, 3); // '*******890' mask(1234567890, -4, '$'); // '$$$$567890'
ヒント
String.prototype.slice()を使って、アンマスク(マスクしない)する文字列を取り出し、String.prototype.padStart()で、元の文字列の長さ分のマスク文字を追加します。第2引数のnumが省略された場合、デフォルトで4文字のアンマスク文字を確保します。またnumに負の値が指定された場合は、文字列の先頭部分をアンマスクします。第3引数のmaskが省略された場合、デフォルトのマスク文字に*を使います。
const mask = (cc, num = 4, mask = '*') => `${cc}`.s____(-num).p_______(`${cc}`.l_____, mask);
6 compactWhitespace
連続するホワイトスペース文字(スペース、タブ、改ページ、改行)をホワイトスペース文字1文字に置き換えます。次の実行結果となるようにcompactWhitespace関数を定義してください。
compactWhitespace('Lorem Ipsum'); // 'Lorem Ipsum' compactWhitespace('Lorem \n Ipsum'); // 'Lorem Ipsum'
ヒント
正規表現とString.prototype.replace()を使うことで、2文字以上のホワイトスペース文字を1文字に置き換えます。
const compactWhitespace = str => str.r______(/\s{2,}/g, ' ');
7 palindrome
与えられた文字列が回文になっているか検証します。回文の場合、true、そうでない場合、falseを返します。次の実行結果となるようにpalindrome関数を定義してください。
palindrome('taco cat'); // true
ヒント
String.prototype.toLowerCase()とString.prototype.replace()を使って非アルファベット文字を除去して小文字に統一し、それからスプレッドオペレータ(...)を使って文字列を文字の配列に変換し、Array.prototype.reverse()、String.prototype.join('')を使って生成した文字列と、元の文字列(非アルファベット文字を除去して小文字に統一したもの)を比較します。
const palindrome = str => { const s = str.t__________().r______(/[\W_]/g, ''); return s === [...s].r______().j___(''); };
8 capitalize
文字列の先頭文字を大文字に変換します。次の実行結果となるようにcapitalize関数を定義してください。
capitalize('fooBar'); // 'FooBar' capitalize('fooBar', true); // 'Foobar'
ヒント
配列の分割代入とString.prototype.toUpperCase()を使って先頭の文字を大文字にします。 ...restには先頭文字を除く文字の配列が格納されるのでArray.prototype.join('')を使って再び文字列に復元しています。引数のlowerRestが指定されなかった場合は残りの文字列(先頭文字を除く)をそのまま使います。lowerRestにtrueが指定された場合は残りの文字列を小文字に置き換えます。
const capitalize = ([first, ...rest], lowerRest = false) => first.t__________() + (lowerRest ? rest.j___('').t__________() : rest.j___(''));
9 byteSize
文字列の長さをbytesで返します。次の実行結果となるようにbyteSize関数を定義してください。
byteSize('😀'); // 4 byteSize('Hello World'); // 11
ヒント
文字列をBlobオブジェクトに変換してsizeプロパティを参照します。
const byteSize = str => new B___([str]).s___;
10 pluralize
入力された数値によって、基準となる文字列を単数系、あるいは複数形にして返します。第1引数にオブジェクトが指定された場合、関数によって返却されるクロージャを返します。これは"s"による単純な複数形の変換だけでなく、指定されたディクショナリに含まれる複数形単語を返却します。次の実行結果となるようにpluralize関数を定義してください。
pluralize(0, 'apple'); // 'apples' pluralize(1, 'apple'); // 'apple' pluralize(2, 'apple'); // 'apples' pluralize(2, 'person', 'people'); // 'people' const PLURALS = { person: 'people', radius: 'radii' }; const autoPluralize = pluralize(PLURALS); autoPluralize(2, 'person'); // 'people'
ヒント
numが-1か1の場合、単数系の単語を返却します。numがそれ以外の値の場合、複数形の単語を返却します。第3引数のpluralが省略された場合、デフォルトで第2引数のwordに"s"を連結した文字列を複数形の単語として処理するので、必要に応じてカスタマイズすることができます。第1引数のvalがオブジェクトの場合、複数形の単語を格納したディクショナリを保持したクロージャを返却します。
const pluralize = (val, word, plural = word + 's') => { const _pluralize = (num, word, plural = word + 's') => [1, -1].i_______(Number(num)) ? word : plural; if (typeof val === 'object') return (num, word) => __________(num, word, val[word]); return __________(val, word, plural); };
答え
お疲れ様でした。答えはこちらの記事を参考に。