【解決】二次元配列の要素同士が連動(?)する条件と回避方法が分かりません。
Posted: 2022年12月13日(火) 15:56
RPGツクールMZの質問というよりJavaScriptの質問になってしまいそうで恐縮ですが。
二次元配列で現在所持しているアイテムを管理しています。
複数の条件が重複する行のアイテム個数を1行の個数へひとまとめにして残りの行へ0を代入する処理を、
プラグインから実行する関数によって試みています。
まとめ処理の前段階として二次元配列を次のようにソートしています。
現在確認できる限りこれでソートはうまくいっているようなので、次に重複行の統合の処理を試みます。
これがうまくいけばあとは3列目が0の行をfilterなどで消せるかと思うのですが、どうもうまくいきません。
たとえば ↑こちらの二次元配列を処理した場合、最終結果は ↑このように悲惨です。 ↑最初のソートはうまくいっているようなのですが、 1行目の3列目へ2行目の3列目の値を加算しようとする時点で連動(?)しており、
2行目の3列目へ0を代入すると1行目の3列目まで0になってしまって、
以降の処理がおかしくなるようです。
上記のコードでは加算する値の入る配列をいったんtmpForAddへコピーして別の配列として扱うことを試みていますが、当初の直接加算するやり方、concatや[...]を使う方法でも結果は同じでした。
配列そのものは変数のように代入しても参照元は同じなのでconcatなどでコピーしないと分けられないということまでは分かったのですが、要素同士の連動というのは、どうしても調べきれませんでした。
配列の要素同士を足し算するのがダメなのかと思って、ローカル変数を宣言してそちらへ格納してから加算しましたがやはり連動しました。
整数を直接足しても連動しました。
これらの要素を連動させなくするか、あるいは複数行を1まとめにする別の良い方法がございましたら、ご教示頂けますと幸いです。
二次元配列で現在所持しているアイテムを管理しています。
複数の条件が重複する行のアイテム個数を1行の個数へひとまとめにして残りの行へ0を代入する処理を、
プラグインから実行する関数によって試みています。
まとめ処理の前段階として二次元配列を次のようにソートしています。
コード: 全て選択
$gameVariables.value(DBvalNum).sort(function(a, b) {
//1列目は昇順。
if (Number(a[0]) > Number(b[0])) return 1;
if (Number(a[0]) < Number(b[0])) return -1;
//2列目も昇順。
if (Number(a[1]) > Number(b[1])) return 1;
if (Number(a[1]) < Number(b[1])) return -1;
// 4列目も昇順。
if (Number(a[3]) > Number(b[3])) return 1;
if (Number(a[3]) < Number(b[3])) return -1;
//3列目をいったん降順に。
if (Number(a[2]) > Number(b[2])) return -1;
if (Number(a[2]) < Number(b[2])) return 1;
//3列目も昇順。
if (Number(a[2]) > Number(b[2])) return 1;
if (Number(a[2]) < Number(b[2])) return -1;
return 0;
});
コード: 全て選択
for (let i = 0; i < $gameVariables.value(DBvalNum).length -1; i++) {
console.log("実行i" + i);
console.log($gameVariables.value(DBvalNum)[i][2]);
if($gameVariables.value(DBvalNum)[i][2] == 0){
console.log("i側何もしない");
console.log($gameVariables.value(DBvalNum)[i][2]);
//先頭の個数が0なら何もしない
}else{
if($gameVariables.value(DBvalNum)[i][0] == $gameVariables.value(DBvalNum)[i+1][0] && $gameVariables.value(DBvalNum)[i][1] == $gameVariables.value(DBvalNum)[i+1][1] && $gameVariables.value(DBvalNum)[i][3] == $gameVariables.value(DBvalNum)[i+1][3] && $gameVariables.value(DBvalNum)[i][2] > 0){
let tmpForAdd = []; //要素同士の代入や加算の際に一時的に配列をコピーするためのローカル変数。
for(let j = i + 1; j < $gameVariables.value(DBvalNum).length -1 +1; j++){
if($gameVariables.value(DBvalNum)[i][0] == $gameVariables.value(DBvalNum)[j][0] && $gameVariables.value(DBvalNum)[i][1] == $gameVariables.value(DBvalNum)[j][1] && $gameVariables.value(DBvalNum)[i][3] == $gameVariables.value(DBvalNum)[j][3] && $gameVariables.value(DBvalNum)[j][2] > 0){
if($gameVariables.value(DBvalNum)[i][2] == 0){
//先頭の個数が0なら何もしない
console.log("j側何もしない");
console.log($gameVariables.value(DBvalNum)[i][2]);
}else{
console.log("j加算前v81[i][2] ="+$gameVariables.value(DBvalNum)[i][2] + ": i= " + i);
console.log("j加算前v81[j][2] ="+$gameVariables.value(DBvalNum)[j][2] + ": j= " + j);
tmpForAdd = Array.from($gameVariables.value(DBvalNum));
$gameVariables.value(DBvalNum)[i][2] += tmpForAdd[j][2];
console.log("j加算後v81[i][2] ="+$gameVariables.value(DBvalNum)[i][2] + ": i= " + i);
console.log("j加算後v81[j][2] ="+$gameVariables.value(DBvalNum)[j][2] + ": j= " + j);
$gameVariables.value(DBvalNum)[j][2] = 0;
console.log("jへ0代入後v81[i][2] ="+$gameVariables.value(DBvalNum)[i][2] + ": i= " + i);
console.log("jへ0代入後v81[j][2] ="+$gameVariables.value(DBvalNum)[j][2] + ": j= " + j);
console.log("実行j" + j);
console.table($gameVariables.value(DBvalNum));
//retry0229 = 1; //行削除が行われたので処理が終わったらループ冒頭へ戻る
}
}
}
}
}
}
たとえば ↑こちらの二次元配列を処理した場合、最終結果は ↑このように悲惨です。 ↑最初のソートはうまくいっているようなのですが、 1行目の3列目へ2行目の3列目の値を加算しようとする時点で連動(?)しており、
2行目の3列目へ0を代入すると1行目の3列目まで0になってしまって、
以降の処理がおかしくなるようです。
コード: 全て選択
console.log("j加算前v81[i][2] ="+$gameVariables.value(DBvalNum)[i][2] + ": i= " + i);
console.log("j加算前v81[j][2] ="+$gameVariables.value(DBvalNum)[j][2] + ": j= " + j);
tmpForAdd = Array.from($gameVariables.value(DBvalNum));
$gameVariables.value(DBvalNum)[i][2] += tmpForAdd[j][2];
console.log("j加算後v81[i][2] ="+$gameVariables.value(DBvalNum)[i][2] + ": i= " + i);
console.log("j加算後v81[j][2] ="+$gameVariables.value(DBvalNum)[j][2] + ": j= " + j);
$gameVariables.value(DBvalNum)[j][2] = 0;
console.log("jへ0代入後v81[i][2] ="+$gameVariables.value(DBvalNum)[i][2] + ": i= " + i);
console.log("jへ0代入後v81[j][2] ="+$gameVariables.value(DBvalNum)[j][2] + ": j= " + j);
配列そのものは変数のように代入しても参照元は同じなのでconcatなどでコピーしないと分けられないということまでは分かったのですが、要素同士の連動というのは、どうしても調べきれませんでした。
配列の要素同士を足し算するのがダメなのかと思って、ローカル変数を宣言してそちらへ格納してから加算しましたがやはり連動しました。
整数を直接足しても連動しました。
これらの要素を連動させなくするか、あるいは複数行を1まとめにする別の良い方法がございましたら、ご教示頂けますと幸いです。