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

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

ただいまの
回答率

88.78%

配列とループの組み合わせについて

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 411

kakeru99

score 13

(↓)の配列があります

// 市区町村の数
let area = [39, 33, 54];

let city =[
'千代田区OK中央区OK港区OK新宿区OK文京区NG・・・',
'横浜市NG川崎市OK横須賀市OK・・・',
'千葉市OK銚子市NG市川市NG・・・'
];

cityの文字列があらかじめ配列であるとしてOKかNGかを検索して一致するかどうかをifで判定させ、それを上記の市区町村の数だけループさせるとした場合どのように組めばいいでしょうか?

自分なりに組んでみたこと。

let z = 0;
for (m = 0; m < city; m++) {
        if (city[m].indexOf(area[z]) !== -1) {

        } else {

        }
}

もしわかる方がいれば教えて頂けると恐縮です。
宜しくお願い致します。

質問への追記・修正

  • areaは市区町村の数
  • areaとcityは1:1で対応している
  • cityは省略していますが要素1なら東京都の市区町村名とOKもしくはNGの文字列が格納されている

得たいプログラムの記述

cityの配列の要素1の場合,areaの要素1の数値分だけループ
→文字列のはじめから順番に検索していきOKと一致するとtrue、NGの場合はfalseをif文で記述。2回目は1回目に一致したその直後から再度検索していく
cityの配列の要素2の場合,areaの要素2の数値分だけループ
→文字列のはじめから順番に検索していきOKと一致するとtrue、NGの場合はfalseをif文で記述。2回目は1回目に一致したその直後から再度検索していく
cityの配列の要素3の場合,areaの要素3の数値分だけループ
→文字列のはじめから順番に検索していきOKと一致するとtrue、NGの場合はfalseをif文で記述。2回目は1回目に一致したその直後から再度検索していく

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • kakeru99

    2019/04/02 12:42

    kei344さん
    すみません。きちんと送信できていなかったようで・・・。
    次はきちんと更新できました。

    キャンセル

  • kei344

    2019/04/02 12:46

    編集ありがとうございます。例えば、「東京の電車遅延があるかどうかの判定」であれば1個でも「NG」が含まれていたら「遅延あり」になりますが、それだけの情報でよいのでしょうか。

    キャンセル

  • miyabi-sun

    2019/04/02 12:52

    > cityの配列の要素1の場合,areaの要素1の数値分だけループ
    これは命令です。
    これでは「お前は黙って俺の言うことに従っていればいいんだ」と怒鳴り散らす無能な上司です。
    目的を書いてください。

    キャンセル

回答 4

+4

難しいデータを難しいまま扱おうとして挫折するのは初心者によくある光景です。
簡単でわかりやすく、扱いやすいデータにしましょう。

let city =[
  '千代田区OK中央区OK港区OK新宿区OK文京区NG',
  '横浜市NG川崎市OK横須賀市OK',
  '千葉市OK銚子市NG市川市NG'
];

// 調査
for (let citiesName of city) {
  console.log(citiesName.split(/(OK|NG)/));
  // ["千代田区", "OK", "中央区", "OK", "港区", "OK", "新宿区", "OK", "文京区", "NG", ""]
  // ["横浜市", "NG", "川崎市", "OK", "横須賀市", "OK", ""]
  // ["千葉市", "OK", "銚子市", "NG", "市川市", "NG", ""]

  // 最後の空文字を削除する
  console.log(citiesName.split(/(OK|NG)/).slice(0, -1));
  // ["千代田区", "OK", "中央区", "OK", "港区", "OK", "新宿区", "OK", "文京区", "NG"]
  // ["横浜市", "NG", "川崎市", "OK", "横須賀市", "OK"]
  // ["千葉市", "OK", "銚子市", "NG", "市川市", "NG"]
}

const cityList = [];
for (let citiesName of city) {
  const result = {};
  const nameAndCondition = citiesName.split(/(OK|NG)/).slice(0, -1);
  for (let i = 0; i < nameAndCondition.length; i += 2) {
    const name = nameAndCondition[i];
    const condition = nameAndCondition[i + 1] === 'OK';
    // もしNGの都市を捨てるならこの行のコメントアウトを削る
    // if (!condition) continue;
    result[name] = condition;
  }
  cityList.push(result);
}
console.log(cityList);
// [
//   {千代田区: true, 中央区: true, 港区: true, 新宿区: true, 文京区: false},
//   {横浜市: false, 川崎市: true, 横須賀市: true},
//   {千葉市: true, 銚子市: false, 市川市: false}
// ]

このままではまだ質問者さんの使いたいデータに届いてないかも知れませんね。
ですが、最初のクソみたいな文字列からすれば大きな前進が出来たと思います。

このように人間が扱いやすいデータに作り変えてから使用する癖を付けましょう。

腕の良いエンジニアは難しい計算を難しい計算のまま行うのではなく、
子供でもわかる簡単な計算に作り変えてしまうから不具合が少ないのです。
この問題をいかに簡単に出来るのかが腕の見せどころなので、色んなデータを作り変えるというのを試してみて下さい。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+1

let city =[
'千代田区OK中央区OK港区OK新宿区OK文京区NG',
'横浜市NG川崎市OK横須賀市OK',
'千葉市OK銚子市NG市川市NG'
];
const oks = city
  .map(e=>e.split(/(OK|NG)/))
  .flatMap(e=> e.reduce( (ac,c,i,ar)=> i % 2 === 1 && c === "OK" ?  ac.concat(ar[i-1]) : ac,[] ))
console.log(oks.includes("中央区"));
console.log(oks.includes("文京区"));

「得たいプログラムの記述」をコード化しました。

ループのやりかたは書いてありましたが、どう結果を得たいのかわからなかったので、stackというのに判定したtrueだか、falseだかを入れてます。

let area = [39, 33, 54];

let city =[
'千代田区OK中央区OK港区OK新宿区OK文京区NG・・・',
'横浜市NG川崎市OK横須賀市OK・・・',
'千葉市OK銚子市NG市川市NG・・・'
];

let stack = [];
for(let areaIdx = 0; areaIdx < area.length; areaIdx++) {
  let boolarrayForArea = [];
  stack.push(boolarrayForArea);
  const str = city[areaIdx];
  let fromIdx = 0;
  let noPos = -1;
  let okPos = -1;
  for(let cityIter = 0; cityIter < area[areaIdx]; cityIter++) {
    ngPos = str.indexOf("NG", fromIdx) === -1 ? Number.MAX_VALUE : str.indexOf("NG", fromIdx) ;
    okPos = str.indexOf("OK", fromIdx) === -1 ? Number.MAX_VALUE : str.indexOf("OK", fromIdx) ;
    const nextPos = Math.min(ngPos, okPos);
    const nextWord = str.substr(nextPos,2);
    if (nextWord === "OK") { boolarrayForArea.push(true); }
    else if (nextWord === "NG") { boolarrayForArea.push(false); }
    else { boolarrayForArea.push(undefined); }
    fromIdx = nextPos + 2;
  }
}
console.log(stack);

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+1

元のコードを生かしてみました。

  let city =[
  '千代田区OK中央区OK港区OK新宿区OK文京区NG・・・',
  '横浜市NG川崎市OK横須賀市OK・・・',
  '千葉市OK銚子市NG市川市NG・・・'
  ];

  for (m = 0; m < city.length; m++) {
    var target = city[m].slice(0);
    while (true){
      var n;

      n = target.indexOf('OK');
      if ( n !== -1) {
        target = target.slice(n+2);
        console.log("OK", target);
        continue;
      }

      n = target.indexOf('NG');
      if ( n !== -1) {
        target = target.slice(n+2);
        console.log("NG", target);
        continue;
      }

      break;
    }
  }  

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

check解決した方法

-1

回答ありがとうございました。
その後、miyabi-sunのソースを元に試行錯誤して下記のように動かすことができました。
質問するのも難しいですが勉強になりました。

<div class="area">
<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>
</div>
let city = [
    '千代田区OK中央区OK港区OK新宿区OK文京区NG',
    '横浜市NG川崎市OK横須賀市OK',
    '千葉市OK銚子市NG市川市NG'
];

const cityList = [];
for (let citiesName of city) {
    let u = city.indexOf(citiesName);
    let u_num = ':nth-of-type(' + (u + 1) + ')';
    const nameAndCondition = citiesName.split(/(OK|NG)/).slice(0, -1);
    for (let i = 0; i < nameAndCondition.length; i += 2) {
        const name = nameAndCondition[i];
        const condition = nameAndCondition[i + 1];
        let num_box = ':nth-of-type(' + (i / 2 + 1) + ')';
        if (condition === 'OK') {} else {
            //OKと一致しない場合の処理
            $('.area ul' + u_num + ' li' + num_box).text("×");
        }
    }
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/10 00:46

    低評価の理由:質問者自身が指示した「得たいプログラム」でない

    キャンセル

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

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

関連した質問

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