JavaScriptでの小技集です。ソースコードでは関数リテラルとしていますが、関数宣言(function文)でも同様に動作します。
数値計算については "Algorithm!" を参照してください。
[ 戻る ]
指定した桁数になるまで数字の左側を0で埋めるゼロパディング (zero padding) をします。Array.joinメソッドは、配列 (array) の全要素を引数 (parameter, argument) で指定した区切り文字 (delimiter) で連結した文字列を作成します。ここで空要素の配列を作成 (Array(digit)
)、区切り文字0で連結 (join('0')
) すると0が並ぶ文字列になります。これを数字の左側に付加し、右側から指定した桁数分だけ切り取ります。負数にも対応しています。
var zero_padding = function(n, digit) {
/* Zero Padding */
var zp = n < 0 ? '-' : '';
n = Math.abs(n);
if (n.toString().length < digit) {
zp += (Array(digit).join('0') + n).slice(-digit);
} else {
zp += n;
}
return zp;
};
[ 戻る ]
指定した小数点 (decimal separator) 以下の桁数で小数 (decimal) を四捨五入します。Number.toFixedメソッドで固定小数点数 (fixed-point number) の文字列に変換してから、先頭に"+"を付加することで数値に戻しています。桁数digitにはNumber.toFixedメソッドの仕様である0以上20以下の値を指定します。
var round = function(n, digit) {
/* 四捨五入して小数第digit位まで求める */
return +n.toFixed(digit);
};
[ 戻る ]
JavaScriptの数値型はIEEE 754で規定された倍精度浮動小数点数 (double precision floating point number) で、1bitの符号部、11bitの指数部 (exponent)、52bit (MSBは常に1なので実質53bit) の仮数部 (fraction) から成ります。このため最小桁で計算誤差が発生することがあります。仮数部の有効桁数は15.95桁 (≃53×log102)ですので、四則計算の結果をNumber.toPrecisionメソッドで15桁に丸めた文字列に変換してから、先頭に"+"を付加することで数値に戻しています。
var double_precision = function(n) {
/* 有効数字15桁(倍精度、double precision)に丸める */
return +n.toPrecision(15);
};
[ 戻る ]
現行の暦法であるグレゴリオ暦 (Gregorian calendar) では、400年に97回の閏年 (leap year) を設けています。
この置閏規則に基づく判定法を以下に示します。
var is_leap_year = function(year) {
/* 閏年判定 (置閏規則) */
return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
};
JavaScriptのDateオブジェクトを利用して2月の月末日(=3月0日の日付)を取得して判定する方法もあります。
var is_leap_year = function(year) {
/* 閏年判定 (3月0日の日付を取得) */
return new Date(year, 2, 0).getDate() == 29;
};
なお、日本の閏年の根拠法はOka Laboratory 備忘録の記事「暦関係の法令」を参照ください。
[ 戻る ]
指定した月の日数を求めます。引数のyearは西暦年、monthは月(1〜12)です。
月の日数を保持した配列を用いる方法は他の言語でも使用できるアルゴリズムです。is_leap_year関数は閏年判定の関数です。
var days_in_month = function(year, month) {
/* 月の日数の取得 (配列) */
return [31, is_leap_year(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][--month];
};
JavaScriptではDateオブジェクトに翌月0日を設定することで月末日が求められ、これを月の日数とすることができます。
var days_in_month = function(year, month) {
/* 月の日数の取得 (Dateオブジェクトで月末日を求める) */
return new Date(year, month, 0).getDate();
};
Internet Explorer 11とFirefoxでは、YYYY-MMの書式で入力してください。
[ 戻る ]
<input>要素のnumber型ではmax属性で最大値を設定できますが、数値を直接入力したときは最大値を超えた値が入力されてしまいます。通常はsubmitによるブラウザの検証機能で十分です。しかし、<form>要素のinputイベントは<form>内の各要素のvalueが変化したタイミングで発火しますので、ブラウザの検証機能が働きません。このため最大値で制限する関数が必要となります。
var limit_max = function(ele_number) {
/* <input type="number">の入力値がmax(最大値)を超えたときの処理 */
var val_max = ele_number.max;
var val_length = ele_number.value.length;
if (+ele_number.value > val_max) {
ele_number.value = ele_number.value.slice(0, --val_length);
if (+ele_number.value > val_max) {
// 上位桁に挿入したときの値が最大値超えの可能性あり
ele_number.value = ele_number.value.slice(0, --val_length);
}
}
};
この関数を<input>要素のnumber型のinputイベントで呼び出します。引数には必ずthisキーワードを指定します。
<input type="number" name="Number1" min="1" max="20" oninput="limit_max(this);">
関数は以下の箇所で使用していますのでご確認ください。
[ 戻る ]
PerformanceインターフェイスのTimeline APIを使うと、関数の実行や処理にかかる時間を計測することできます。
まず、performance.markで計測地点を設定します。複数の計測地点を設定したら、performance.measureで計測地点間の測定を設定します。それから、performance.getEntries系メソッドでPerformanceEntryオブジェクトの配列を取得し、そのdurationプロパティで計測値を取得します。
素因数分解のページで素因数分解、数論的関数値、類判定の実行時間の計測で使用しています。
performance.mark('prime_start');
func_prime();
performance.mark('prime_end');
func_arithmetic();
performance.mark('class_start');
func_class();
performance.mark('class_start');
// 計算・判定の実行時間
performance.measure('timer', 'prime_start', 'prime_end'); // func_prime
performance.measure('timer', 'prime_end', 'class_start'); // func_arithmetic
performance.measure('timer', 'class_start', 'class_end'); // func_class
var timer = performance.getEntriesByName('timer'); // 実行時間値の取得
for (var i = 0; i < timer.length; i++) {
console.log(timer[i].name + ': ' + durationtimer[i].duration);
}
performance.clearMarks();
performance.clearMeasures();
[ 戻る ]
空要素を含む配列変数から空要素を一括して削除するには、filterメソッドを使います。
filterメソッドの引数callbackにBooleanコンストラクタ関数を渡すことで、falsyな値である0、−0、空文字列("")、false、null、undefined、NaNである要素が削除されます。Booleanの引数は1個であるため、callback関数の引数elementが渡されます。
q = p.filter(Boolean);
具体的な使用例は、エラトステネスの篩のソースコードを参照してください。
[ 戻る ]
[ 戻る ]