質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

3110閲覧

tableのセルをjsで連結する

Gr.

総合スコア89

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2018/10/15 08:50

参考:テーブルのセルで 同じ内容だったらマージする

jsに関して全くの素人です。日々手を動かしながら勉強しています。
練習で使った動作確認済みのコードで書き方を理解しようと思い、質問させていただきました。

状況:
・Japanモデルにprefectureカラム&cityカラム
・@japanにデータを.all

html

1<table id="tokyo"> 2 <% @japan.each do |f| %> 3 <tr> 4 <td class="tokyo-td1"><%= f.prefecture %></td> 5 <td><%= f.city %></td> 6 </tr> 7 <% end %> 8</table>

結果:
|東京|港区 |
|東京|墨田区|
|東京|中央区|

わかりにくくて申し訳ないですが、以下のコードで、同じ値(この場合は「東京」)を持つセルが結合されます。

$(function() { var counter = 0; var text =""; var target=""; $($('#tokyo tr:first, .tokyo-td1').get().reverse()).each(function() { if ($(this).text() == text) { counter++; if(target !="") target.remove(); } else { if(target !="") target.attr('rowSpan', counter); counter=1; } text = $(this).text(); target = $(this); }); });

結果(after):
|東京|港区 |
|  |墨田区|
|  |中央区|

わかりにくいですが、東京のrowspanが3になって結合されています。

このスクリプトが理解できていないので、どなたか詳しい方に解説していただきたいです。

※上と同じもの $(function() { var counter = 0; var text =""; var target=""; $($('#tokyo tr:first, .tokyo-td1').get().reverse()).each(function() {  ← Q1:なぜ.reverse()? if ($(this).text() == text) { counter++;  ← Q2:++って何? if(target !="")  ← Q3:(target !="")ってどういうこと?というかこのtargetって具体的にどこを指してる? target.remove(); } else { if(target !="") target.attr('rowSpan', counter); counter=1;  ← Q4:これは何? } text = $(this).text();  ← Q5:この記述は何のため? target = $(this);  ← Q6:この記述は何のため? }); });

コード内にQ1~Q6まで書きました。他にもわからない点がありますが、とりあえず1~6について理解すればわかるかもしれないので、どなたか解説お願いします。

本当に全くの初心者です。お手柔らかにお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

初心者ということで、まずは次のようなアドバイスを送ります。

仕組みがわからないときは実際に動かしてみるのがベターです。
今回のスクリプトの場合、データ割り当て後ののHTMLを用意することで、chromeやIEなどのデバッガで自由に変数を確認することができます。
こういったことができることは非常に有用ですのでやってみてください。

また、プログラミングは結局のところ、人ができることを代わりにやってもらってるわけですので、
自分ならどういうふうにセルを結合するか一度考えてみてください。
大抵、その考えに似たものがコードになっていることが多いです。

次に、Qに答える前にどのような仕組みかをざっくりと述べます。

そのほうがわかりやすいと思うので。これは、ひとつ前に述べたアドバイスを実施してるにすぎませんが…

  1. prefectureのセルをまとめて取得する
  2. セルを下からくっつけるかくっつけないか確認する(下から確認する代わりに反転させている)
    今のセルである$(this)と前のセルであるtargetのテキストを比較して、
    同じ場合: くっつける数(Rowspanの数)を表すcounterを+1する
    異なる場合: 前のセルのRowspanを設定する

という感じです。細かいところは、頭の中で変数の値がどう変わるかを考えてみてください。

次にQへの回答です

javascript

1$(function() { 2 var counter = 0; 3 var text =""; 4 var target=""; 5 // Q1: なぜ.reverse()? 6 // A1: 削除や統合などの処理を行う場合、前から処理すると、 7 // 削除したときに後ろの要素が前に詰まりますよね?それが原因で 8 // 配列の処理がおかしくなるケースがあったりします(処理の内容による)。 9 // 習慣として、後ろから処理してるのかなと推察します。 10 $($('#tokyo tr:first, .tokyo-td1').get().reverse()).each(function() { 11 if ($(this).text() == text) { 12 // Q2: ++って何? 13 // A2: この場合、counter += 1 と同じです。 14 // ++自体はインクリメント演算子といい、詳細はぐぐってください。 15 counter++;   16 // Q3: (target !="")ってどういうこと?というかこのtargetって具体的にどこを指してる? 17 // A3: targetが初期値でないことを確認しています。targetは 18 // ひとつ前のセルを表しますが、初回に限っては 19 // var target = ""とされており、ひとつ前のセルではないです。 20 // 初回はひとつ前のセルが存在しないので妥当な処理だと思います。 21 if(target !="") 22 target.remove(); 23 } else { 24 if(target !="") 25 target.attr('rowSpan', counter); 26 // Q4:これは何? 27 // A4: counterの値を1に初期化しないと、counterの値が増え続け、 28 // 東京以外のセルが出てきた場合にそのセルまでくっつくことになります。 29 // なので、こうしてます。 30 counter=1; 31 } 32 // Q5: この記述は何のため? 33 // A5: セルのテキストを保持しておきます。次の確認で、 34 // 前のセルのテキストとして利用するためですね。 35 text = $(this).text(); 36 // Q6: この記述は何のため? 37 // A6: セルを保持しておきます。次の確認で、前のセルとして利用するためです。 38 target = $(this); 39 }); 40});

投稿2018/10/15 09:53

編集2018/10/15 10:01
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Gr.

2018/10/15 13:05

ppnさん たいへん詳しい回答ありがとうございます! 今のセルである$(this)と前のセルであるtargetのテキストを比較して、同じ場合と異なる場合の処理をif,elseで書いているわけですね。 そして最後尾のtext = $(this).text();とtarget = $(this);でそのセルの情報をキープして次の処理に渡しているのですね。 よくわかりました! 今度はこれを応用した処理を書いてみようと思いますが、たぶんまたどこかでつっかかって質問することになると思うので、見かけたらまた助けてください。 ありがとうございました!
退会済みユーザー

退会済みユーザー

2018/10/15 13:38

はい、その理解であってると思います。頑張ってください^^
guest

0

元ソースは無視してこんな感じでどうでしょう?

script

1<script> 2$(function(){ 3 $($('#tokyo tr').get().reverse()).each(function(){ 4 if($(this).prev('tr').length>0){ 5 var pre=$(this).prev('tr').find('td:eq(0)'); 6 var self=$(this).find('td:eq(0)'); 7 if(pre.text()==self.text()){ 8 pre.attr('rowspan',parseInt(self.attr('rowspan')||"1")+1); 9 self.remove(); 10 } 11 } 12 }); 13}); 14 15</script> 16<table id="tokyo"> 17<tbody> 18<tr> 19<td>東京</td> 20<td>港区</td> 21</tr> 22<tr> 23<td>東京</td> 24<td>港区</td> 25</tr> 26<tr> 27<td>神奈川県</td> 28<td>横浜市</td> 29</tr> 30<tr> 31<td>神奈川県</td> 32<td>横浜市</td> 33</tr> 34<tr> 35<td>東京</td> 36<td>港区</td> 37</tr> 38<tr> 39<td>東京</td> 40<td>墨田区</td> 41</tr> 42<tr> 43<td>東京</td> 44<td>中央区</td> 45</tr> 46<tr> 47<td>神奈川県</td> 48<td>横浜市</td> 49</tr> 50</tbody> 51</table>

投稿2018/10/15 09:36

編集2018/10/15 09:41
yambejp

総合スコア114839

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問