JavaScriptの中のsplitとjoin関数の階段の使い方

5818 ワード

Javascriptは2つのかなり強力で開発者に愛されている関数:splitとjoinの対立の関数を持っています.この2つの関数は、stringとarrayの2つのタイプを置き換えることができます.つまり、配列は、順番に文字列に変換され、逆もまた然りです.私たちはこの2つの関数を余すところなく発揮することができる.この二つの関数を紹介します.
String.prototype.split separatorは文字列を配列に分割し、任意のパラメータlimitは生成配列の最大lengthを定義します.

"85@@86@@53".split('@@'); //['85','86','53'];
"banana".split(); //["banana"]; //( thanks peter (-: )
"president,senate,house".split(',',2); //["president", "senate"]
Array.prototype.join(separator)
オプションのパラメータseparatorは配列を文字列に変換します.separatorを提供しないと、カンマをこのパラメータ値にします.

["slugs","snails","puppy dog's tails"].join(' and '); //"slugs and snails and puppy dog's tails"
['Giants', 4, 'Rangers', 1].join(' '); //"Giants 4 Rangers 1"
[1962,1989,2002,2010].join();
これらのアプリケーションを見てみます.
replacceAllという簡単な関数は原生のreplace関数とは違って、正則式を使う必要なく大域のサブ文字列として置換できる.

String.prototype.replaceAll = function(find, replaceWith) {
  return this.split(find).join(replaceWith); 
}

"the man and the plan".replaceAll('the','a'); //"a man and a plan"

小さい文字列については、1文字で置換された原生関数よりも性能が弱い(ここでは正規表現の2つの追加の関数を指す)が、mozilaでは、この文字が2つ以上または3つ以上の文字であれば、この使用関数は正規表現よりも速い.
この関数はサブ文字列の一致する個数をとることができます.またこの関数は正則を直接必要としない.

String.prototype.occurences = function(find, matchCase) {
  var text = this;
  matchCase || (find = find.toLowerCase(), text = text.toLowerCase());
  return text.split(find).length-1;  
}

document.body.innerHTML.occurences("div"); //google home page has 114
document.body.innerHTML.occurences("/div"); //google home page has 57
"England engages its engineers".occurrences("eng",true); //2
repeat

この関数はプロトタイプ.jsから参考にしてきました.

String.prototype.repeat = function(times) {
  return new Array(times+1).join(this);  
}

"go ".repeat(3) + "Giants!"; //"go go go Giants!"

その素晴らしいところはジョン関数の使用にあります.焦点はこのseparatorパラメータの値です.そして、この基礎配列はいくつかの未定義のvalue値だけを含んでいます.この点をより明確に説明するために、上の例を作り直します.

[undefined,undefined,undefined,undefined].join("go ") + "Giants
ジョインの前に各配列要素が文字列に変換されます.ここでは空の文字列です.このrepeat関数の応用は配列字面量によって配列を定義する数少ない応用である.
limitパラメータを使うと、私はsplit関数のlimitオプションパラメータをあまり使いません.このlimitを使った例を紹介します.

var getDomain = function(url) {
  return url.split('/',3).join('/');
}

getDomain("http://www.aneventapart.com/2010/seattle/slides/");
//"http://www.aneventapart.com"
getDomain("https://addons.mozilla.org/en-US/firefox/bookmarks/");
//"https://addons.mozilla.org"

数値を修正するメンバーは正則を混ぜて使うと、join、splitが簡単に配列メンバーを修正できます.しかし、この関数は思ったほど難しくはありません.指定された配列の各メンバーの前で指定された文字列を削除するのが主な機能です.

var beheadMembers = function(arr, removeStr) {
  var regex = RegExp("[,]?" + removeStr);
  return arr.join().split(regex).slice(1);
}

//make an array containing only the numeric portion of flight numbers
beheadMembers(["ba015","ba129","ba130"],"ba"); //["015","129","130"]

残念なことに、この関数はIEの中で失効しました.彼らはsplitから最初の空いているメンバーを外しました.この関数を修正します.

var beheadMembers = function(arr, removeStr) {
  var regex = RegExp("[,]?" + removeStr);
  var result = arr.join().split(regex);
  return result[0] && result || result.slice(1); //IE workaround
}
私たちはなぜこの技術を使いますか?Emascript 5の中でarrayのmap関数を使わないですか?

["ba015","ba129","ba130"].map(function(e) {
  return e.replace('ba','')
}); //["015","129","130"] 
実際の運用では、実行可能な時に、私は通常原生のmap関数を使います.以下の例は勉強の道具としてだけですが、joinとsplitの呼び出し文法はもっと簡潔で直接的です.最も興味深いことに、それは非常に効率的であり、特に小さな配列に対しては、FFとSafariの中でより効率的に表現されている.大きな配列に対しては、map関数がより適切である.(すべてのブラウザで)ジョインとスプリット関数の関数呼び出しが少ないです.

//test 1 - using join/split
var arr = [], x = 1000;
while (x--) {arr.push("ba" + x);}

var beheadMembers = function(arr, regex) {
  return arr.join().split(regex).slice(1);
}

var regex = RegExp("[,]?" + 'ba');
var timer = +new Date, y = 1000;
while(y--) {beheadMembers(arr,regex);};
+new Date - timer;

//FF 3.6 733ms
//Ch 7  464ms
//Sa 5  701ms
//IE 8 1256ms

//test 2 - using native map function
var arr = [], x = 1000;
while (x--) {arr.push("ba" + x);}

var timer = +new Date, y = 1000;
while(y--) {
  arr.map(function(e) {
    return e.replace('ba','')
  });
}
+new Date - timer;

//FF 3.6 2051ms
//Cr 7  732ms
//Sf 5  1520ms
//IE 8  (Not supported)

パターンマッチング配列は常にモードマッチングを実行する必要がありますが、文字列はありません.正規表現は文字列で使用できますが、配列では使用されません.配列を文字列に変換してモードマッチングに使う強さは、この文章で述べられている範囲をはるかに超えています.簡単な応用を見せてください.
競歩の試合結果を行列に保存する必要があると仮定します.目的は競技者と彼らの記録時間を交互に配列に置くことです.このような保存モードが正しいかどうかをjoinと正規表現で検証することができます.次のコードは、2つの連続した名前を検索することによって記録時間が失われた状況を探し出すことです.

var results = ['sunil', '23:09', 'bob', '22:09', 'carlos', 'mary', '22:59'];
var badData = results.join(',').match(/[a-zA-Z]+,[a-zA-Z]+/g);
badData; //["carlos,mary"]