JavaScriptで配列をコピーする

JavaScriptで配列をコピーするときは次のような注意が必要です。

a=[10,20,30];
b=a;

配列変数aを配列変数bにコピーしています。
これで配列変数bをaの代わりに使うことができます。

次にpopを使ってaの最後の要素をクリアします。

a.pop();

この場合、bには何も影響しないように思われますが、実行結果は次のようになります。

a=[10,20]
b=[10,20]

bもaと同じく最後の要素がクリアされます。
つまり「b=a」とすると各要素がコピーされるのではなく「bはaを参照する」ということになるのです。
したがって各要素をコピーするためには次のようにします。

a=[10,20,30];
for(i=0;i<a.length;i++){
  b[i]=a[i];
}
a.pop();

実行結果は次の通り。

a=[10,20]
b=[10,20,30]

意図通り、aだけが処理されました。

なお次のような簡単な方法もあります。
sliceを使うと配列を部分的に抜き出すことができます。
第1引数にセットした位置から第2引数にセットした位置の前まで抜き出します。
第1引数に「0」をセットし、第2引数を省略すると、最初から最後までを抜き出しますので、配列の各要素をコピーするのと同じ効果があります。

a=[10,20,30];
b=a.slice(0);
a.pop();

switchとifで速いのはどっち?(JavaScript)

前に、VBAで「SelectCaseとIfで速いのはどっち?」というのを調べてみましたが、今度はJavaScriptで同じことをしてみました。なお、SelectCaseはswitchに置き換えます。
サンプルコードは省略しますが、同様の関数を作り、10000回繰り返したときの実行時間を測りました。

サンプル 時間
配列変数 0.5124秒
switch 0.0688秒
if(単純) 0.2594秒
if(終了) 0.0359秒
if(場合分け) 0.0359秒

面白いのはifの場合分けを使った場合の効果に違いが見られなかったことです。

「同じ文字が2個並んだ文字列」の正規表現

「book」の「oo」のように文字の繰り返しを見付ける正規表現について調べました。

JavaScriptの場合

まず/.{2}/という表現を思い付きますが、これでは「同じ文字が2個並んだ文字列」になりません。単に「文字が2個並んだ文字列」です。1個目と2個目の文字が異なってもよいからです。
そこで次のようにします。

str="book";
ret=str.match(/(.)\1/g);

「oo」が返されます(正確にはret[0]として)。
JavaScriptの正規表現では「\1」を使うと括弧に挟まれた部分を取得できます。
/(.)/とすると任意の1文字が取得でき、\1に格納されます。
/(.)\1/とすると/\1\1/のように「同じ文字が2個並んだ文字列」を探すことになります。

秀丸の場合

検索文字列として「(.)\1」を指定します。
もちろん正規表現にチェックを入れます。
もし「同じ文字が2個以上並んだ文字列」を検索するならば「(.)\1+」とするとよいでしょう。
「ぱみゅぱみゅ」のように「同じ文字列が2回並んだ文字列」ならば「(.+)\1」だとうまくいきます。

JavaScriptのmatchの戻り値

JavaScriptのmatchは正規表現に合致した文字列を配列で返します。
「g」を付けない場合と「g」を付ける場合で内容が変わります。

gを付けない場合 gを付ける場合
0個目 合致した部分全体
1個目 1個目の括弧で括られた部分
2個目 2個目の括弧で括られた部分
0個目 最初に合致した部分全体
1個目 2番目に合致した部分全体

gを付けない場合のサンプル

str="xayxbyxcy";
ret=str.match(/(x.)y/);

ret[0]="xay"
ret[1]="xa"

「x□y」という文字列を探しています。
gがないので一つ見つけたら終わりです。
戻り値の0個目は合致した部分全体です。「xay」になります。
戻り値の1個目は合致した部分のうち括弧に挟まれた部分です。「(xa)y」と見て「xa」になります。

gを付ける場合のサンプル

str="xayxbyxcy";
ret=str.match(/(x.)y/g);

ret[0]="xay"
ret[1]="xby"
ret[2]="xcy"

上のサンプルと同じく「x□y」という文字列を探しています。
gがあるので合致する文字列をすべて見付けます。
戻り値の0個目は最初に合致した文字列です。
戻り値の1個目は2番目に合致した文字列です。
戻り値の2個目は3番目に合致した文字列です。
括弧に挟まれた部分を返すようなことはありません。

長音を含む文字列を辞書順でソート

辞書の言葉の並び順はアイウエオ順ですが、「ー」という伸ばす音、長音があるときは、その前の音によって判断されます。
その前の音がア段ならば「ア」、イ段ならば「イ」となります。
例えば「ワード」ならば「ワアド」、「キー」ならば「キイ」として並び順が決まります。

ワア≫ワー≫ワアド≫ワード≫ワイ

となります。 (さらに…)

JSONの\uXXXXをデコード

TwitterAPIなどを使い、JSON形式でデータを取得した場合、文字列が次のようになっている場合があります。

\u4eca\u671d\u306f

初めて見ると「文字化けか」と思ってしまうかもしれませんが、これはJSONのルール通りなんだそうです。
この「\uXXXX」形式は「Unicode文字エスケープシーケンス」、「unicode escape sequence」などと呼ぶそうです。
2.4.1 Unicode 文字エスケープ シーケンス (C#)
Unicodeにおける文字番号を4桁の16進数に置き換えて、頭に「\u」を付けます。
これをJavaScriptを使って人間が読める形にする方法(デコード)を調べました。
単純な方法

簡単なのは次のようにJavaScriptでページに書く方法です。

document.write("\u4eca\u671d\u306f");

これで次のように表示されます。

今朝は

関数を使う方法

「json_str_decode」という関数を作ってみました。
このケースでは「\」が(JavaScriptの)エスケープシーケンスに該当してしまうので「\\」のようにしないと正しく認識しません。

document.write(json_str_decode("\\u4eca\\u671d\\u306f"));
function json_str_decode(str){
  arrs=str.match(/\\u.{4}/g);
  var t="";
  for(i=0;i<arrs.length;i++){
    t+=String.fromCharCode(arrs[i].replace("\\u","0x"));
  }
  return(t);
}

次のようにテキストエリアなどに貼り付けて使う場合には「\\」とする必要がありません。

<textarea id="ta">\u4eca\u671d\u306f</textarea>
<div id="mydiv"></div>
var a=document.getElementById("ta").value;
document.write(json_str_decode(a));

「東京電力の電気使用状況 API」を使う

東京電力から電力の使用状況が公開されましたが、これをJSON形式で扱えるAPIを公開しているサイトがありました。 (さらに…)

Googleマップ KML/CSV相互変換

Googleマップは、位置情報をプロットして、自分の地図(マイマップ)をつくることができます。
このデータはKMLという形式でエクスポートすることができます。
これをCSVに変換するためのツールを作りました。

Googleマップ KML/CSV相互変換

CSVに変換し、Excelなどで編集した後、またKMLに変換して、マイマップにインポートすることもできます。 (さらに…)

生年から厄年を知る「厄年早見表」

初詣に行ったところ、すでに厄年を過ぎていたことに気付いた次第。
何が分かりにくいかというと「数え年」の意味。
生まれたときに既に1歳、年を越すと1歳プラス、というのが数え年。
Wikipediaの説明は次の通り。 (さらに…)

JavaScriptで発車標を作る

Yahoo!知恵袋にこんな質問がありました。
「駅の発車標をJavaScriptで再現させたい」

次の電車を案内する表示のことを「発車標」と呼ぶのだそうです。
これをJavaScriptで作りたいとのこと。
随分、漠然とした感じで一言では答えられませんが、面白そうなテーマなので、サンプルを作ってみました。 (さらに…)

新しい記事 | 古い記事

タグ

カテゴリー

最近の投稿

最近のコメント

固定ページ

アーカイブ

stabucky

写真

メタ情報