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

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

ただいまの
回答率

87.37%

多次元配列と再帰呼び出しについて

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,114

score 61

多次元配列で[[0,1], [2,3], [4,5]](数字は重複しないランダムな値を取得したいです。)みたいなものを作りたいのですが、main関数の結果は下記の写真のように[x,x],[x,x]となってしまいます。
イメージ説明

そこで3つ質問です。
① [[0,1], [2,3], [4,5]]みたいに配列の中に配列を作るときは下記のmain関数の処理をどのように変更すれば実現できますか?

② rand()をstimu変数に入れているのでmain(stimu)の値が何回やっても同じになるのは分かるんですが、どうすればランダムに取り出してmain()のendList[]に追加できますか?

③ rand()の取り出す処理でdocument.write("<div>"+combo+"</div>");を追加すると結果は下記の写真みたいに42個の組み合わせ全てを取得できるんですが、return combo;すると最初の1組だけ取得されてしまいます。なぜでしょうか?
イメージ説明

//main関数
function main(stimu) {
  var endList = [];

  endList.push([stimu[0], stimu[1]]);
  console.log(endList[0]);
  endList.push([stimu[0], stimu[1]]);
  console.log(endList[1]);
}


//ランダムな値を取得
function rand() {
  var movieList = [0, 1, 2, 3, 4, 5, 6];
  var movie_1, movie_2;

  // 組み合わせの用意
  var movieComb = [];
  for (var i = 0; i < movieList.length; i++) {
    for (var j = 0; j < movieList.length; j++) {
      if (movieList[i] !== movieList[j]) {
        movieComb.push([movieList[i], movieList[j]]);
      }
    }
  }

  // シャッフルする
  for (var i = movieComb.length - 1; i > 0; i--) {
      var r = Math.floor(Math.random() * (i + 1));
      var tmp = movieComb[i];
      movieComb[i] = movieComb[r];
      movieComb[r] = tmp;
  }
  // 取り出す
  for (var i = 0; i < movieComb.length; i++) {
      movie_1 = movieComb[i][0];
      movie_2 = movieComb[i][1];
      var combo = movieComb[I];
      document.write("<div>"+combo+"</div>");
      return combo;
  }
}
var stimu = rand();

どうか、解決方法をよろしくお願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • tanishi_a

    2019/09/29 23:05 編集

    ちゃんと読んでないですが、下記の i が大文字なのは怪しいですね。

    > movieComb[I];

    キャンセル

  • gyoruo

    2019/09/30 00:58

    ありがとうございます。
    そこを直してもできませんでした、、、

    キャンセル

  • tanishi_a

    2019/09/30 06:33

    そうですね。その他のところ含めて回答欄に書いたので確認してみてください。

    キャンセル

回答 2

checkベストアンサー

0

③ は、 combo という1要素しか返してないからですね。
たぶん返したいのは 全部の組み合わせなので、こうだと思います。

// 取り出す
var combos = [];
for (...) {
   ...
   var combo = movieComb[i]; // ※ 大文字 => 小文字にした
   combos.push(combo);
}
return combos;

①②は読んだら追記します。

## 以下、追記

③については、
rand 関数内の // 取り出す 以下は不要で、return movieComb; したらいいと思います

①②については、

やろうとしてることは、こういうことだと思いますが、

function main(stimu) {
  var endList = [];
  endList.push(stimu[Math.floor(Math.random() * stimu.length)]);
  endList.push(stimu[Math.floor(Math.random() * stimu.length)]);
  console.log(endList);
}

これだと重複してしまうのと、既にシャッフルしてあるようなので、以下のように順番に取り出せば良いと思います。

function main(stimu) {
  var endList = [];
  endList.push(stimu[0]);
  endList.push(stimu[1]);
  console.log(endList);
}

・・・

※ それから 本質とは関係ない補足ですが、

関数名ですが rand() は乱数を返す関数に見えてしまうので、別の名前にしたほうが良いと思いました。 なんでもいいですが、 getRandomCombinations() とか。 stimu も何だかわからないですが。

それと、タイトルの「再帰呼び出し」は関係ないように思います。

・・・

### さらに追記

もとのコードを見るに、書きたかったのは、こういうことだったかも?

//main関数
function main() {
  var endList = [];

  endList.push(rand());
  endList.push(rand());
  console.log(endList);
}


//ランダムな値を取得
function rand() {
  var movieList = [0, 1, 2, 3, 4, 5, 6];

  // 組み合わせの用意
  var movieComb = [];
  for (var i = 0; i < movieList.length; i++) {
    for (var j = 0; j < movieList.length; j++) {
      if (movieList[i] !== movieList[j]) {
        movieComb.push([movieList[i], movieList[j]]);
      }
    }
  }

  // シャッフルする
  for (var i = movieComb.length - 1; i > 0; i--) {
      var r = Math.floor(Math.random() * (i + 1));
      var tmp = movieComb[i];
      movieComb[i] = movieComb[r];
      movieComb[r] = tmp;
  }

  // 取り出す
  return movieComb[Math.floor(Math.random() * movieComb.length)];
}

main();

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

こんな感じで

const a=Array(7).fill(null).map((x,y)=>y);
var b=[];
a.forEach(x=>a.forEach(y=>b.push([x,y])));
b=b.filter(x=>x[0]!==x[1]).map(x=>[x,Math.random()]).sort((x,y)=>x[1]-y[1]).map(x=>x[0]);
console.log(b);

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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