プロが教えるわが家の防犯対策術!

Google Apss Scriptを使ってスプレッドシートで小テスト作成のスクリプトを作ろうとしています。

二次元配列で以下のような問題のデータがあります。最後のAnswerの部分の数字(1行目なら3)は選択肢の3番目(1行目ならindividual)が答えというようにできています。

[[Japanese, Choice1, Choice2, Choice3, Choice4, Answer]
[個人・個々の, opposite, microscopic, individual, separate, 3.0]
[必要な, necessity, necessarily, need, necessary, 4.0]]

Choice1~Choice4の選択肢をランダムに並べ替え、同時に答えも書き換えるようにしたいのですが、どうしたらいいでしょうか?

例えば、1行目を以下のように変えたいのです。
[1, 個人・個々の, opposite, microscopic, individual, separate, 3]

[1, 個人・個々の, microscopic, individual, opposite, separate, 2]

ネットで検索しても、特定の列を基準に行を並べ替える例はたくさんあるのですが、特定の行の列を並べ替えるという例が見つかりませんでした。

よろしくお願いいたします。

A 回答 (3件)

> 2次元配列のままで各行の要素の順番(列)をランダムに並べ替える



// 行数分の範囲から2次元配列を取る
2次元配列 = dataSheet.getRange(行,列,行数,8).getValues();

// 各行の 4列目 から 8列目 を書き換える
2次元配列.forEach(row => {
_ shufflePartial(row, 3, 4); // row[3] から row[6] を書き換え
_ row[7] = 並び替え後の選択肢;
});

参考)
https://developer.mozilla.org/ja/docs/Web/JavaSc …
    • good
    • 0
この回答へのお礼

忙しい中、再度の回答ありがとうございました。

このようなコードをさっとかけるスキルのある回答者様がうらやましいです。

自分一人では到底できないようなことなのでとても助かりました。おかげで望み通りのことができるようになりました。まだよくわからない部分があるのですが、調べて理解していきたいと思います。

お礼日時:2024/02/05 21:32

いや、こりゃ難問だ。



最初に断っておくけど、全然GASなるモノに付いては知らない。
いや、Google Apps Scriptなるプログラミング言語の存在は知ってはいるんだけど、生憎「JavaScriptにそっくりだ」と言う知識しかないんだ。
んで、普段はJavaScript絡みの問題には関わらないようにしてんだけど(HTMLやCSS絡みのコードは読みたくない・笑)、この問題自体は面白そうなんで、JavaScriptで書いてはみた。JavaScriptだと上手くは動くんだ。

JavaScriptによる実装例:
https://www.ideone.com/F0xMai

ところが、だ。
Google Drive上でGASとしてこいつを実行しようとすると、エラーを喰らうんだよなぁ。

TypeError: Cannot read properties of undefined (reading '0')
shufflePartial

「なんでやねん?」とか思って、ネット上で色々調べてはみたんだけど、解決策が見つからん(笑)。
ゴメン、ギブアップだ(笑)。
アレだな、あんまよう知らんプログラミング言語に手を出しちゃダメだ、って事だな(笑)。何かGAS「独特の」制限があるっぽい。
反省してる(笑)。
誰かGASのエキスパートが登場する事を望む、よ(苦笑)。

写真: 書いたJavaScriptコードをGoogle V8 + Node.jsで実行した例。これが要求された「二次元配列を行毎に条件に従ってランダムソートした結果」になってると思う。
「二次元配列の中の各行の要素をランダムに並」の回答画像3
    • good
    • 0
この回答へのお礼

返信が遅くなり申し訳ありません。忙しい中、回答ありがとうございます。

Ogre7077様の回答をもとに解決できました。まだまだプログラミングもよくわかっていないので、またの機会がございましたらよろしくお願いいたします。

お礼日時:2024/02/09 07:38

/**


配列内の特定列だけを並び替えます.
@param a 並び替える配列
@param s 対象列の最初の位置
@param n 対象列の数
@see Fisher–Yates shuffle
*/
function shufflePartial(a, s, n) {
_ let i = n, x, y;
_ while (i > 0) {
_ _ x = (i--) * Math.random() | 0;
_ _ y = a[s+x];
_ _ a[s+x] = a[s+i];
_ _ a[s+i] = y;
_ }
}

shufflePartial(特定の行, 1, 4);
並べ替え後の選択肢の番号 = 特定の行.indexOf(答え);

参考)
https://en.wikipedia.org/wiki/Fisher%E2%80%93Yat …
https://developer.mozilla.org/ja/docs/Web/JavaSc …
    • good
    • 0
この回答へのお礼

忙しい中、早速の回答ありがとうございました。

ご教示いただいた方法を使って、元のスプレッドシートのデータから各行を2次元配列に格納し、それを1次元配列にして並べ替えて、別の2次元配列に格納するというようなやり方でできました。

実際の問題データはA列が番号、B列が日本語、C列が英語、D列からG列が選択肢1~4、H列が解答となっていましたので、それに合わせて変更しました。

2次元配列のままで各行の要素の順番(列)をランダムに並べ替えるということはできないのでしょうか?2次元配列のままだとできないようです(私のやり方が間違っていればすみません)。

とりあえず、頑張って書き直したの以下のようなコードです。

function myfunction(){
~途中省略~
var data =[];
for (a=2; a <=dataSheetLastRow; a++){
var question1 =[];
var question2 = [];
question2 = dataSheet.getRange(a,1,1,8).getValues();
question1 = question2.flat();
var c = question1[7]+2;
var answer = question1[c];
shufflePartial(question1, 3, 4)
var answerNum = question1.indexOf(answer)-2;
question1.pop();
question1.push(answerNum);
data.push(question1);
}
~以下省略~
}

function shufflePartial(a, s, n) {
let i = n, x, y;
while (i > 0) {
x = (i--) * Math.random() | 0;
y = a[s+x];
a[s+x] = a[s+i];
a[s+i] = y;
}
}

お礼日時:2024/02/05 14:07

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A