引数の文字列を全て連結する関数について
var config={
connect:{character:',',expand:true,operator:':'}
/*
character……何の文字列で連結するか
expand……展開するかどうか(true/false or number) 数字の場合は、展開する回数
operator……オブジェクト( {a:'a',b:'b'}など )の場合、キーと値を連結する文字列(key+operator+value)
*/
};
function connect(){
var connectString=config.connect.character,expand=config.connect.expand,operator=config.connect.operator,n=0;
var subCallee=function(arg){
var text=arg,i;
if(typeof arg=='object'){
var number=arg.length;
switch(expand){
case true:
text=subCallee(arg[0]);
foreach(arg,function(i,key,value){ //i……ループ回数-1 key……Object:キー,Array:i value……値
if(i){ //0回目はすでに再帰呼び出し済み
text+=connectString+subCallee(value); //再帰呼び出しで、展開
}
});
break;
case false:
case 0: //展開回数0(0)もしくは、展開しない(false)場合
text=arg[0];
foreach(arg,function(s){
if(s){
text+=connectString+this; //展開しないので、そのまま引数をつなげる。
}
});
break;
default:
if(typeof expand=='number'){ //expandがNumber型だった時
if(n>expand){ //nは最初に定義済み。展開回数が、指定された回数を越えた場合には、終了。
break;
}
foreach(arg,function(i,key,value){
i(i){
text+=connectString+subCallee(value);
}
});
n++; //何回展開したか、数える。
break;
}
return false;
}
}
return text;
};
return subCallee(arguments); //最初にargumentsを渡して、subCalleeを呼ぶ。
}
このように定義されていますが、Array型とObject型はtypeofしても、共にobjectが帰ってくるため、判別できません。
何か判別する方法はないでしょうか?
また、Object型の場合には、valueをkey+config.connect.operator+value(つまり、key:valueのような感じ)にしたいのですが、
text+=character+key+operator+subCallee(value);
とし、
var a=config.connect;
a.character='<>';
alert(connect({a:0,b:1}));
としましたが、alert表示されたのは、
undefined<>b:1
でした;
Object,Arrayの判定はしてないので、Arrayを入れてみたら↓
alert(connect(['a','b',['c',['d']]]));
↓
a<>1:b<>2:c<>1:d
となっています。
展開順に考えて、以下のようになるのが妥当かな、と思ったのですが;
まず、['a','b',[]] なので、
0:a<>1:b<>[]
で、次に[]の中の、['c',[]]が展開されるので、
<>2:c<>[]
最後に、['d']が展開されるので、
<>1:d
よって、
0:a<>1:b<>2:c<>1:d
かな、と。。
実際はa<>b<>c<>dでいいので、ここは気にしなくていいですw
Object,Arrayの判定方法と、Objectの場合、key:valueを取得する方法を、宜しくお願いします。
お礼
なるほどです。 自分なりに考えたんですが・・。浅はかでした。