例えば、sqrt(x) という関数を作成するとき、x がスカラならば sqrtS(4)、ベクトルならば sqrtV([4, 9]) のように、個別の関数を作るのではなく、sqrt(x) としてまとめられれば便利です。
s = sqrt(4) → s = 2
v = sqrt([4, 9]); → v = [2, 3]
それをここでは、「引数タイプのpolymorphism」といいます。
(s = sqrtV([4]) とする規則にすれば一つの配列型関数で済むでしょうが、不注意のエラーが頻出するでしょう。)
これを実現するには、関数側で引数のタイプを判別する必要があります。
スカラとベクトルの判別
if (typeof x == "number") {スカラ}; else {ベクトル};
ベクトルとマトリックスの判別
if (x[1].length > 0) {マトリックス}; else {ベクトル};
// スカラーとベクトルの処理を別途に記述できるとき
function fun1(x) {
if (typeof x == "number") { // スカラーのときの処理
var rtns = x + 10;
return rtns;
}
else { // スカラーのときの処理
var rtnv = [];
for (var i=0; i<x.length; i++) {
rtnv[i] = x[i] + 10;
}
return rtnv;
}
}
var x = fun1(3); // 13
var v = fun1([1,2]); // [11, 12]
=================================================================================
// スカラをサイズ1のベクトルとしてベクトル処理だけを記述するとき
// 関数内では新ベクトルでの処理を記述する必要がある
function fun2(x) {
var xx = []; // 新ベクトルにする
if (typeof x == "number") xx[0] = x; else xx = x;
var rtn = [];
for (var i=0; i<xx.length; i++) { // ベクトルとして処理
rtn[i] = xx[i] + 10; // 新ベクトル名での処理
}
if (typeof x == "number") return rtn[0]; // スカラーとして戻す
else return rtn; // ベクトルとして戻す
}
=================================================================================
// ベクトルとマトリックス(各行の最大値を求める)
function fun3(x) {
if (x[1].length > 0) var type="m"; else type = "v"; // ベクトルなら存在しないので fause になる
if (type == "v") {
var xmax1 = x[0];
for (var j=1; j<x.length; j++) {
xmax1 = Math.max(xmax1, x[j]);
}
return xmax1;
}
else {
var xmax = [];
var imax = x.length;
for (var i=0; i<imax; i++) {
xmax[i] = x[i][0];
var jmax = x[i].length;
for (var j=1; j<jmax; j++) {
xmax[i] = Math.max(xmax[i], x[i][j]);
}
}
return xmax;
}
}
var v = [1, 5, 3];
fun3(v); // 5
var m = [ [1, 5, 3], [4, 6] ];
fun3(m); // [5, 6]
=================================================================================
// マトリックスをベクトルに変換する
function fun4(x) {
x = x.flat(); // マトリックスをベクトルに変換
var xmax = x[0];
for (var i=1; i<x.length; i++) {
xmax = Math.max(xmax, x[i]);
}
return xmax;
}
var v = [1, 5, 3];
fun4(v); // 5
var m = [ [1, 5, 3], [4, 6] ];
fun4(m); // 6
=================================================================================