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

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

ただいまの
回答率

90.62%

  • JavaScript

    15863questions

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

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 487

M.Nishimura

score 18

 前提・実現したいこと

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

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

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

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

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

 該当のソースコード

var j = 1;
for(var key in targetData){
    console.log(j);
    for(var l=0;l<titleNo.length;l++){
            //タイトルの場合はスキップ
            if(j == titleNo[l]){
                rowNo.push('TITLE' + l);
                j=j+1;
                break;
            }else{
                rowNo.push(targetData[key]);
                break;
            }
        }
    j=j+1;
}

 試したこと

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"}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • M.Nishimura

    2018/04/18 20:40

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

    キャンセル

  • defghi1977

    2018/04/18 20:42

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

    キャンセル

  • defghi1977

    2018/04/19 08:55

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

    キャンセル

回答 3

+3

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


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

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

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


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

またここで、j = 1の時に、j == titleNo[0]が真となるようですから、titleNo[0]は1であるはずです。なので、(細かい話を除けば)j = 2の時にはj == titleNo[0]は必ず偽になりますから、if文のブロックが実行されることはなく、j = 2のまま外側のループを終えます。
 
 
 
解決方法については、このコードの仕様が不明の部分が多いため、もう少し情報が必要です。「このような入力に対してこのような出力をしたい」のように補足してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/19 14:01

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

    キャンセル

checkベストアンサー

+1

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

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

var rowNo = new Array(0),
  l = 0;

for(var key in targetData){
  if (key == titleNo[l]) {
    var rowSingle = {};
    rowSingle.title = 'TITLE' + (l + 1);
    rowSingle.valuesList = new Array(0);

    rowSingle.valuesList.push(targetData[key]);

    rowNo.push(rowSingle);

    l++;
  } else {
    rowNo[rowNo.length - 1].valuesList.push(targetData[key]);
  }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/19 14: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++;
    }
    }

    キャンセル

  • 2018/04/19 14:29 編集

    申し訳ない、当該行の型指定を間違っておりました。
    回答を修正いたしましたので、
    再度、回答通りに書いてみていただけないでしょうか?

    もしくは、どうしても、最終のデータを一次元配列にしたい場合は、そのように回答を修正いたします。

    キャンセル

  • 2018/04/19 17:26

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

    キャンセル

0

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

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

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

// 見出のNO取得
var regexp = /dispTitle_../g;
var matchStr= rtnhtml;
var titleNo = {};
titleNo=matchStr.match(regexp);
// NOだけ取得
for(var i=0; i<titleNo.length; i++){
    titleNo[i] = titleNo[i].replace('dispTitle_','');
    titleNo[i] = titleNo[i].replace('"','');
    titleNo[i] = titleNo[i].replace('\"','');
    titleNo[i] = titleNo[i];
}
//タイトルNO分の配列をJSON形式に変換
var titleJson = tranlateJson(titleNo);
var margeTitle = JSON.parse(titleJson);
ohtml = ohtml + '<div id="ResultContent"></div><div id="hiddenresult" style="display: none;">';
// 検索結果データ
for(var i = 1, len = rt.length;i<len;i++){
    var targetData = rt[i];
    //title行とマージ
    var rowNo = Object.assign({}, targetData, margeTitle);
    ohtml = ohtml + '<div class="result"><ul id="result_' + i + '" class="result">';
    for(var key in rowNo){
        ohtml = ohtml + '<li id = "result' + i + '_' + key + '">' +rowNo[key] +'</li>'
    }
    ohtml = ohtml + '</ul></div>';
}
elm.innerHTML = ohtml + '</div>';

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    15863questions

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