人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

javascriptの勉強をしています。
今回は2つの質問です。

1)for文のループに関してで、
ある数字に含まれている(その数字より小さい)奇数だけパイプ線で区切りたいのですが、
こんな感じ→ 1|3|5|7|9|・・・(ある数字(例:15))

for(var j=1;j<=15;j++)
document.write(2*j-1+"|");

とdocument.writeを使えばうまくいくのですが、
他の方法で要素を結合しようとすると、

for(var j=1;j<=15;j++)
document.myForm.data.value=2*j-1+"|";

ループが終了していて1番高い数字が1つだけ表示されてしまいます。
調べたところクロージャなどを使って解決するようなのですが、
いまいち理解ができないのでよろしくお願いします。

2)ある配列から最小を求めるときに、
var min = Math.min.apply(null, hairetu);

ある限定の数字(例えば-5)が最小の場合は、
その要素(-5)の次に最小の要素を求める場合はどう書けばいいでしょうか?
(ようは-5だけは最小にしたくない)

また同じように、負(マイナス)の要素を相手にせずに、
正(プラス)だけの最小値を求める場合はどう書けばよいでしょうか?

分かりにくいようなら追記いたします。よろしくお願いします。

●質問者: tontonpokopoko
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:JavaScript Write いまいち クロージャ パイプ
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● van-dine
●70ポイント

(1)

document.myForm.data.value += 2 * j - 1 + "|";

「+=」ではなく「=」を使ってるため変になります。

(2)

hairetu2 = (hairetu.concat()).sort(function (x, y){return x - y})
for(var i = hairetu2.length - 1; hairetu[i] == hairetu[hairetu2.length - 1]; i--)
//正の時は「?; hairetu[i] > 0; ?」
{
 min = hairetsu[i];
}

1行にはなりませんでしたが、これで動きます。

なお、

(hairetu.concat()).sort(?)

と書かずに

hairetu.sort(?)

と書くと、hairetsuがソートされてしまうのでご注意を。

◎質問者からの返答

van-dineさま、回答をありがとうございます。

1)の質問ですが参考になります。

もし動的なページ(ある数字、例でいうと「15」が一定ではない)でイベントハンドラで動作した場合に、

1|3|5|7|9|・・1|3|5|7|9|・・1|3|5|7|9|・・(3回クリック)

とイベント(クリック)をするごとに前回の値(セット)の上に足されるようですが、

これを最後にイベントを起こしたセットだけにはできないでしょうか?

1|3|5|7|9|・・を1セットと言う意味です。

2)の質問は検証中です。


2 ● kebo987654
●100ポイント ベストアンサー

1)

たとえば

string+="abcd";

なら

string=string+"abcd";

と同じ意味になりまから、

document.myForm.data.value+=~;

としてしまうと、

document.myForm.data.value=document.myForm.data.value+~;

のように現在フォームに書かれている文字列に~を加えることになります。

ですから文字列をいったん格納する変数を用意しておいて、変数のなかで文字列を完成させてから代入させてやるとうまくいきます。

var str="";//最初に空文字列を定義します。
for(var j=1;j<=15;j+=2)
 str+=j+"|";//定義した文字列変数に文字列を足していきます。
document.myForm.data.value=str;//完成した文字列を表示します。

ただ、JavaScriptで文字列を何回も結合したい場合は、+演算子を使うよりも

配列.join("")とする方が効率が高い場合が多いです。(ブラウザにもよりますがIEなら確実にそうなります)

例:

var l=(15/2>>0)+15%2,//配列の長さ(ループ回数)は予め求められる
 str=new Array(l);
for(var i=0;i<l;++i)
 str[i]=i*2+1;
str.join("|");//ついでに区切り文字"|"を指定して結合するとよりスマート?

2)

正の最小値の求め方ですが、

負の数は符号なし整数にしてしまえば正の数よりも必ず大きい数になりますから、整数のみを扱うのでしたら配列に代入する時点で符号なし整数にしておいてMath.min.applyすればいいと思います。

/*x>>>0で符号なし整数にできる*/
var array=[-8>>>0,-4>>>0,0>>>0,1>>>0];

/*負が正より大きくなっているので、正の最小値0が表示される*/
Math.min.apply(null,array);//0

/*配列から値を取り出すときはx>>0のようにして符号付きに戻す*/
array[0]>>0;//-8
◎質問者からの返答

kebo987654さま、いつもありがとうございます。

1)の説明も分かりやすく書いていただいて、とても勉強になりました。

2)の方法はビット演算子というやつでしょうか。

今まで勉強したことがないので、もう少し具体的に教えてもらえないでしょうか?

例えば、

前回のリストボックスでユーザに書き込んでもらった値の配列が「ret」にあります。

この場合はどう書けばいいでしょうか?

「ret」にある正の最小値の求め方です。

よろしくお願いします。


3 ● uunfo
●30ポイント

イベント(クリック)をするごとに前回の値(セット)の上に足されるようですが、

これを最後にイベントを起こしたセットだけにはできないでしょうか?

以下のようにすればいいのでないかな。

毎回値を初期化するということ。

document.myForm.data.value="";
for(var j=1;j<=15;j++)
document.myForm.data.value+=2*j-1+"|";
◎質問者からの返答

回答をありがとうございます。

すでに解決済みでしたが、

他の質問の動作確認のため質問を締め切らず申し訳ありませんでした。

参考にさせていただきます。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ