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

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

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

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

Q&A

解決済

3回答

1034閲覧

JavaScriptでループ意図したループをしてくれない

Otazoman

総合スコア44

JavaScript

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

0グッド

2クリップ

投稿2018/04/18 09:43

編集2018/04/18 23:40

前提・実現したいこと

リスト出力をする際に、タイトル行を飛ばして処理を
行いたいと考えてJavaScriptでタイトル行番号を格納した配列を
読み込んで、要素番号と比較しタイトル行番号と一致した場合に
TITLEと出力させる処理を行いたいと考えJavaScriptを記述しました。

発生している問題・エラーメッセージ

タイトル行番号は複数あるのですが、先頭の1個の行番号としか比較を
行ってくれずに最初の1個しか処理が行われていません。

本来は以下の様になる想定ですが
TITLE0
リスト内の値1
リスト内の値2
リスト内の値3
TITLE1
リスト内の値5

以下の様になってしまいます。
TITLE0
リスト内の値1
リスト内の値2
リスト内の値3
リスト内の値5

該当のソースコード

JavaScript

1var j = 1; 2for(var key in targetData){ 3 console.log(j); 4 for(var l=0;l<titleNo.length;l++){ 5 //タイトルの場合はスキップ 6 if(j == titleNo[l]){ 7 rowNo.push('TITLE' + l); 8 j=j+1; 9 break; 10 }else{ 11 rowNo.push(targetData[key]); 12 break; 13 } 14 } 15 j=j+1; 16}

試したこと

jが1から開始しているのが原因かと思い、0に変更しましたが
結果は変わりませんでした。

補足情報

rowNoに格納しているデータの内容を取込し、titleNoに格納されている
行番号とjの値を比較しています。
j自体は意図している通り行数分実行されていますがtitleNoの箇所が
きちんとループしてくれていません。
かなり悩みましたが、console.logで動きを追ってもどうしていいか
分からないので、ご助力お願いできますでしょうか。

※targetDataの構造です
|行番号|"表示する内容"|
以下の様な内容となります。
{1:"テスト1",2:"テスト2",3:"テスト3"}

console.log(JSON.stringify(targetData))の結果です。

{"1":"VER","2":"null","3":"5000","4":"1885","5":"YAKU","6":"アク","8":"aaa","9":"http://bbb.jp/pamph/aa/1.pdf","10":"2017/04/01","11":"○","12":"○","13":"×","14":"○","15":"×","16":"×","17":"×","18":"×","19":"×","20":"×","28":"日額×5、日額×日数","29":"1日目","30":"20日","31":"1,000日","33":"5日未満は額×5、日数5日以上は、日額×日数","34":"1日目から","35":"120日","36":"1,000日","38":"日額×5、日数5日以上は、日額×日数","39":"-","40":"120日","41":"1,000日","43":"日額×5。\n5日以上は、日額×日数","44":"1日目から","45":"120日","46":"1,000日","48":"1回につき40倍、\nそれ以外は×10倍","49":"1回につき","50":"1回につき","51":"-","53":"-","54":"-","56":"同額","57":"気・ガそれぞれの期間中、1,000日","58":"-","59":"null","60":"-","61":"-","62":"-","63":"-","64":"-","66":"×","67":"null","68":"null","69":"-","71":"-","72":"-","74":"-","75":"-","77":"null"}

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

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

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

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

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

defghi1977

2018/04/18 09:45

targetDataの中身を提示して下さい
defghi1977

2018/04/18 10:00

targetDataの内容短くありませんか?コードを端折る部分を間違えています.
Otazoman

2018/04/18 11:40

番号と内容をまとめた形のもので、87個並んでいる形となります。console.logで出力された値で87個のうち一部を抜粋しました。
defghi1977

2018/04/18 11:42

console.log(JSON.stringify(targetData)) で出力されたものを提示して下さい.
defghi1977

2018/04/18 23:55

すまん, ここまでして貰ったのだけれど何をしたいのかが全く見えてきません.
guest

回答3

0

js

1 for(var l=0;l<titleNo.length;l++){ 2 //タイトルの場合はスキップ 3 if(j == titleNo[l]){ 4 rowNo.push('TITLE' + l); 5 j=j+1; 6 break; 7 }else{ 8 rowNo.push(targetData[key]); 9 break; 10 } 11 }

この部分ですが、if...else文のブロック両方にbreak文がありますから、必ずループを抜けます。
なので、このループが2周目に行くことはありません。

つまり、以下のコードと等価です。

js

1 if(j == titleNo[0]){ 2 rowNo.push('TITLE' + 0); 3 j=j+1; 4 }else{ 5 rowNo.push(targetData[key]); 6 }

ですから、"TITLE1"という値が得られることはないでしょう。

またここで、j = 1の時に、j == titleNo[0]が真となるようですから、titleNo[0]は1であるはずです。なので、(細かい話を除けば)j = 2の時にはj == titleNo[0]は必ず偽になりますから、if文のブロックが実行されることはなく、j = 2のまま外側のループを終えます。



解決方法については、このコードの仕様が不明の部分が多いため、もう少し情報が必要です。「このような入力に対してこのような出力をしたい」のように補足してください。

投稿2018/04/19 01:26

Lhankor_Mhy

総合スコア36115

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

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

Otazoman

2018/04/19 05:01

ご回答ありがとうございます。 初歩的なミスですいません。ご指摘ありがとうございます。
guest

0

ベストアンサー

keyに、JSONで得たkey番号が振られているようなので、
jを持つ必要がないように思います。
そして、titleNoをいちいちforループさせているのが原因だと思います。
なので、外部にインデックスを持たせるべきなのは、むしろlの方でしょう。
また、結果のデータを二次配列で持つべきかと思います。

以下でいかがでしょうか。

javascript

1var rowNo = new Array(0), 2 l = 0; 3 4for(var key in targetData){ 5 if (key == titleNo[l]) { 6 var rowSingle = {}; 7 rowSingle.title = 'TITLE' + (l + 1); 8 rowSingle.valuesList = new Array(0); 9 10 rowSingle.valuesList.push(targetData[key]); 11 12 rowNo.push(rowSingle); 13 14 l++; 15 } else { 16 rowNo[rowNo.length - 1].valuesList.push(targetData[key]); 17 } 18}

投稿2018/04/19 01:25

編集2018/04/19 05:30
miyabi_takatsuk

総合スコア9528

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

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

Otazoman

2018/04/19 05:12

ありがとうございます。 rowSingle.valuesList = new Array(0);の箇所で 「未定義または NULL 参照のプロパティ 'valuesList' は取得できません」と なってしまいました。 titleNo[l]には見出行の番号のみが格納されている状態で targetDataには該当見出しに表示させるデータが存在している状態です。 ひとまず下記で動かすとタイトル行は取得されずにデータだけが 取得されて表示される状態です。 var l=0; for(var key in targetData){ if (key !== titleNo[l]) { rowNo.push(targetData[key]); } else { var rowSingle = []; rowNo.push('TITLE' + (l + 1)); l++; } }
miyabi_takatsuk

2018/04/19 05:32 編集

申し訳ない、当該行の型指定を間違っておりました。 回答を修正いたしましたので、 再度、回答通りに書いてみていただけないでしょうか? もしくは、どうしても、最終のデータを一次元配列にしたい場合は、そのように回答を修正いたします。
Otazoman

2018/04/19 08:26

すいません。今回はどうしても一次元配列でないと うまく動かないので一次元配列に修正いただいてよろしいでしょうか。
guest

0

結局はそもそものロジックから見直しました。

リストの番号が歯抜けになるのでそのリストのKEY番号が
抜けている箇所にタイトル行の番号を埋めるという処理でしたので

見出しNOを取得してそれを配列化した上でリストのデータと同じ
形式のJSONデータに変換しマージさせるという処理で対応いたしました。

JavaScript

1// 見出のNO取得 2var regexp = /dispTitle_../g; 3var matchStr= rtnhtml; 4var titleNo = {}; 5titleNo=matchStr.match(regexp); 6// NOだけ取得 7for(var i=0; i<titleNo.length; i++){ 8 titleNo[i] = titleNo[i].replace('dispTitle_',''); 9 titleNo[i] = titleNo[i].replace('"',''); 10 titleNo[i] = titleNo[i].replace('\"',''); 11 titleNo[i] = titleNo[i]; 12} 13//タイトルNO分の配列をJSON形式に変換 14var titleJson = tranlateJson(titleNo); 15var margeTitle = JSON.parse(titleJson); 16ohtml = ohtml + '<div id="ResultContent"></div><div id="hiddenresult" style="display: none;">'; 17// 検索結果データ 18for(var i = 1, len = rt.length;i<len;i++){ 19 var targetData = rt[i]; 20 //title行とマージ 21 var rowNo = Object.assign({}, targetData, margeTitle); 22 ohtml = ohtml + '<div class="result"><ul id="result_' + i + '" class="result">'; 23 for(var key in rowNo){ 24 ohtml = ohtml + '<li id = "result' + i + '_' + key + '">' +rowNo[key] +'</li>' 25 } 26 ohtml = ohtml + '</ul></div>'; 27} 28elm.innerHTML = ohtml + '</div>';

色々とご助力いただきありがとうございました。

投稿2018/04/23 04:14

Otazoman

総合スコア44

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問