末尾の , (カンマ) を取り除きたかった話

あるチェックボックスのチェックが入っている一覧をクエリストリングにしてやりたかった。 ?hoge=1,2,3 みたいに。でも ?hoge=1,2,3, になってしまった。

こんな風に無理やりやろうとしてた

$.each でまわして末尾を消し去る

var checked__ids = $("input[name=obj_id]:checked");
var ids = '';
$.each(function(){
  ids += $(this).val();
});
ids = ids.substring(0, ids.length - 1);

でもなんかうまくいかない

追記 そりゃうまくいかないわけだ

$.each にchecked_ids わたしてないじゃん。そもそも , もいれてないし

var checked__ids = $("input[name=obj_id]:checked");
var ids = '';
$.each(checked_ids, function(){
  ids += $(this).val();
  ids += ",";
});
ids = ids.substring(0, ids.length - 1);

いちおうできた。でもかっこわるい。変数は多いし、泥臭いし、あんまりいい実装じゃない気がする。

Array.prototype.join.call(NodeList)が使えるのでは?

やってみた。なんかだめだった

ids = Array.prototype.join.call(checked__ids);

結局こう教えてもらった

$('input[name=obj_id]:checked').map(function(){ return $(this).val() }).get().join(',');

すごい。軽く読み解こう。
jQuery の map は ary, callback を呼び出すものもあるけど、 callback だけのもある。なので map() で $(this).val() をとりだす

$('input[name=obj_id]:checked').map(function(){ return $(this).val() })
// ['1', '2', '3']

このまま join したいけど

$('input[name=obj_id]:checked').map(function(){ return $(this).val() }).join(',')
// TypeError: Object [object Object] has no method 'join'

なので .get() で生のDOM要素に変換する必要がある。というわけで最初のようなコードになった。すごい。
あとハマりどころとしては一度 $("input[name=hoge]") で取得してしまうと NodeList(Arrayっぽいけど Array ではない配列っぽいリストっぽいなにか) になってしまうっぽい、そのまま map() するということかな?そんなことなかった

追記 コメントより

kk6 2012/08/09 23:23
すみません、説明の仕方がちょっと悪かったですね。
DOM要素に変換するというよりも、配列にしてやる必要があったわけです。

.get()は $('input').get(0) みたいにインデックスを指定すると、DOM要素がひとつだけ取り出せます。
引数無しだとDOMの配列そのものが取り出せます。
配列が取り出せたのであとはjoinするだけ、といった感じです。

「引数なしだとDOMの配列そのものが取り出せる」ってところがポイントですね。Pythonでも a =b[:] みたいな話に通じるところがあります

追記2 コメントより

os0x 2012/08/10 02:52
jQueryオブジェクトには、 toArray というまさに配列に変換するためのメソッドがあるので、そっちを使ったほうが格段にリーダブルなコードになりますよ。

たしかにこの方法で試したところたしかに変換できました。いいですね。つまり以下のようになります。

$("input[name=obj_id]:checked").map(function(){ return $(this).val() }).toArray()..join(','))