関数を作っていて、こんな機能があったらいいなと思いました。
function(a, b, c, d, e);
function([a, b, c, d, e]);
function([a, b], [c, d], e);
function([a, [b, c], d], e);
function([a, [b, [c], d], e);
これらの全てで同じように動く機能。
引数、argumentsを、配列に変換する方法は
Array.prototype.slice.call(arguments)
このようにすればいいことは以前から知っていますが、
結局のところ、そこから、多次元配列を1次元配列に変更しなければいけないと思ったので、実装してみました。
多次元配列から1次元配列への展開
var arrayMultiDimensionExpand = function (arrayValue) {
var result = [];
var f = function (value) {
for (var i = 0, l = value.length; i < l; i += 1) {
var arrayItem = value[i];
if (Array.isArray(arrayItem)) {
f(arrayItem);
} else {
result.push(arrayItem);
}
}
};
f(arrayValue);
return result;
};
内部で再起呼び出しを使って出力しています。
動作確認
動作確認は次のとおりです。
世界最小テストフレームワークのcheckを使っています。
var check = function (a, b, message) {
if (a === b) {
return true;
}
if ((typeof message === 'undefined')
|| (message === null)) {
message = '';
} else {
message = 'Test:' + message + '\n';
}
message = message +
'A != B' + '\n' +
'A = ' + a + '\n' +
'B = ' + b;
alert(message);
return false;
};
check('1,2,3,4', arrayMultiDimensionExpand([1,2,3,4]).join());
check('1,2,3,4', arrayMultiDimensionExpand([[1,2],3,4]).join());
check('1,2,3,4', arrayMultiDimensionExpand([[1,2],[3,4]]).join());
check('1,2,3,4,5,6', arrayMultiDimensionExpand([1,2,3,4,5,6]).join());
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[1,2],[3,4], 5, 6]).join());
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[1,2,3,4], 5, 6]).join());
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[1,[2,3],4], 5, 6]).join());
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[[1,[2,3]],4], [5, 6]]).join());
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[[[[[1],2],3],4],5],6]).join());
check('1,2,3,4,5,6,7,8', arrayMultiDimensionExpand([[1,[2,3],4], [5, [6, 7], 8]]).join());
これで、多次元配列で引数を渡されても、対応できる関数を作ることができます。
全文
全文です。
web と node.js と windows wsh wsf で動作確認しました。
orValue という、第一引数と、第二引数以降のものを比較する関数を作って、動作確認しました。
orValueは、第一引数に関数を指定すると、第二引数以降が展開されてしまうので、比較できないですね。
var alert = alert || function (message) {
console.log(message);
};
var main = function (testName) {
//----------------------------------------
//・assert関数
//----------------------------------------
// ・ value が true でなければ
// 例外を出力する関数
// ・ 他言語でよく使う
//----------------------------------------
var assert = function (value, message) {
if ((typeof message === 'undefined')
|| (message === null)) {
message = '';
}
if (typeof value !== 'boolean') {
throw new Error('Error:' + message);
}
if (!value) {
throw new Error('Error:' + message);
}
};
//----------------------------------------
//・check関数
//----------------------------------------
// ・ 2値が一致するかどうか確認する関数
//----------------------------------------
var check = function (a, b, message) {
if (a === b) {
return true;
}
if ((typeof message === 'undefined')
|| (message === null)) {
message = '';
} else {
message = 'Test:' + message + '\n';
}
message = message +
'A != B' + '\n' +
'A = ' + a + '\n' +
'B = ' + b;
alert(message);
return false;
};
//----------------------------------------
//・Array.isArray
//----------------------------------------
// ・Array.isArray が存在しない環境(WSHなど)
// のために実装
// ・参考:書籍:JavaScriptパターン P51
//----------------------------------------
Array.isArray = Array.isArray || function (arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
var arrayMultiDimensionExpand = function (arrayValue) {
var result = [];
var f = function (value) {
for (var i = 0, l = value.length; i < l; i += 1) {
var arrayItem = value[i];
if (Array.isArray(arrayItem)) {
f(arrayItem);
} else {
result.push(arrayItem);
}
}
};
f(arrayValue);
return result;
};
check('1,2,3,4', arrayMultiDimensionExpand([1,2,3,4]).join(), '01');
check('1,2,3,4', arrayMultiDimensionExpand([[1,2],3,4]).join(), '02');
check('1,2,3,4', arrayMultiDimensionExpand([[1,2],[3,4]]).join(), '02');
check('1,2,3,4,5,6', arrayMultiDimensionExpand([1,2,3,4,5,6]).join(), '02');
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[1,2],[3,4], 5, 6]).join(), '02');
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[1,2,3,4], 5, 6]).join(), '02');
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[1,[2,3],4], 5, 6]).join(), '02');
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[[1,[2,3]],4], [5, 6]]).join(), '02');
check('1,2,3,4,5,6', arrayMultiDimensionExpand([[[[[[1],2],3],4],5],6]).join(), '02');
check('1,2,3,4,5,6,7,8', arrayMultiDimensionExpand([[1,[2,3],4], [5, [6, 7], 8]]).join(), '02');
var orValue = function (value, compares) {
assert(2 <= arguments.length);
var argsArray = arrayMultiDimensionExpand(arguments);
for (var i = 1, l = argsArray.length; i < l; i += 1) {
if (value === argsArray[i]) {
return true;
}
}
return false;
};
var a = 1;
check(true, orValue(a, 1), '01');
check(true, orValue(a, 1, 2), '02');
check(true, orValue(a, 1, 2, 3), '03');
check(false,orValue(a, 2, 3, 4), '04');
check(true, orValue(101, [101, 102]));
check(true, orValue(102, [101, 102]));
check(false,orValue(103, [101, 102]));
check(true, orValue(103, [101, 102], 103));
check(false,orValue(104, [101, 102], 103));
check(true, orValue(104, [101, 102], 103, 104));
check(true, orValue(104, [101, 102], [103, 104]));
check(false,orValue(105, [101, 102], [103, 104]));
check(true, orValue(105, [101, 102], [103, 104], 105));
check(true, orValue(102, [[[101, [102], 103], 104], 105]));
check(true, orValue(103, [[[101, [102], 103], 104], 105]));
check(true, orValue(105, [[[101, [102], 103], 104], 105]));
check(false,orValue(106, [[[101, [102], 103], 104], 105]));
alert(testName + ' test finish');
}
if (typeof module !== 'undefined') {
module.exports = main;
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title></title>
<script src="script.js"></script>
<script>
var alert = function (message) {
console.log(message);
};
window.addEventListener("load",function(eve){
// main('load');
},false);
</script>
</head>
<body>
<form name="form01">
<table class="table02">
<tr>
<td>
<input type="button" value="Test01" onclick="main('web')"
style="width:150px;">
</td>
</tr>
</table>
</form>
</body>
</html>
var main = require('./script.js');
main('node.js');
node call_script_node.js
pause
<?xml version="1.0" encoding="shift-jis" ?>
<job>
<script language="JavaScript" src=".\script.js"></script>
<script language="JavaScript">
<![CDATA[
var alert = function (message) {
WScript.Echo(message);
}
main('WSH_wsf');
]]>
</script>
</job>
ライブラリ
このあたりの仕組みなどを組み込んだ、汎用関数ライブラリを作っています。
既存のJavaScript環境の(たぶん)全てに対応できるように組んでいるので、
ご参考や、ご利用など、どうぞです。
stsLib.js/Source/stsLib.js at master · standard-software/stsLib.js
https://github.com/standard-software/stsLib.js/tree/master/Source/stsLib.js
追記
........もしかして......
joinして、splitしたら、同じ処理ができるのではないか???
多次元配列に対して、[1,2,3,[4,5, [6,7]]].join()
は、かなりいい感じの値を返してくれている。
必要なら調べてみてください。