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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

解決済

1回答

2457閲覧

GASで.replace()を使用する際、.slice()を挟んでも破壊的に処理される問題

takaD

総合スコア315

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

0クリップ

投稿2020/05/27 05:50

前提・実現したいこと

スプレッドシートにデータベースを構築し、その情報を取り出して、いろいろ情報を取得したり加工したりしようとしています。

その際、1つのデータベースから、やりたい処理(親子構造に関する物や単価等の情報走査)に応じて、
情報を一部置換する必要がでてきました。

そこで諸々データベースの取得と、それを一部変更するプログラムを作成し、実行したところ、
自分としては、取得したデータベースと変更したデータベースの2つが出来ると思っていたところ、
両方とも変更されたデータベースになってしましました。

該当のソースコード

GAS

1function main() { 2const DB1 = LibraryDB().slice(); 3//情報を取得 4Logger.log(DB1) 5 6const DB2 = masterConvertCostDB(DB1).slice(); 7//取得した情報を変更 8 9Logger.log(DB1) 10//同じLogger.log(DB1)なのに、ログを見ると、情報が変わっている。 11} 12 13//区分にある情報がBならAに、CならDに置換しています。 14//(実際のコードでは置換以外にもいろいろやってはいます) 15function masterConvertCostDB(DB){ 16var DB2 = DB.slice(); 17 LibraryReplaceFt(DB2, 3, "B","A") 18 LibraryReplaceFt(DB2, 3, "C","D") 19return DB2 20 21} 22 23 24function LibraryReplaceFt(arr, col, from, to) 25{ 26 var a = arr.slice(); 27 for( var b in a) 28 { 29 a[b][col] = String(a[b][col]).replace(from,to).slice(); 30 } 31return a 32} 33 34 35function LibraryDB(){ 36var DB = [ 37 ["No.","親番","子番","区分","単価"], 38 [1,"A01","A01A","A",100], 39 [2,"A01","A01B","B",20], 40 [3,"A01","A01C","C",350], 41 [4,"A02","A02A","A",2], 42 [5,"A02","A02B","B",1.8], 43 [6,"A02","A02C","D",100], 44 [7,"B01","B01A","A",1500], 45 [8,"B01","A02B","C",1100], 46 ]; 47return DB 48} 49 50

試したこと

諸々調査していくと、結局のところ、自分でコード化した
LibraryReplaceFt(arr, col, from, to)
が原因であることは判明したのですが、自分の中の知識では、
処理が破壊的に行われるのであれば、 .slice()を挟めば解決するという知識しかなく、
.slice()をいたるところに設置しても解決できない状態になっております・・・

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

2次元配列の場合、.slice()でコピーされるのは1次元だけで、要素の配列は共有状態のままとなります。

完全にコピーしたい場合、JSON化できるもの(配列・オブジェクトリテラル以外のオブジェクトが含まれない)の場合はJSON.parse(JSON.stringify(配列))のような手段があります。

投稿2020/05/27 06:06

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takaD

2020/05/27 23:34

回答ありがとうございます。 JSON系はまだ勉強していない方向なのでこれから勉強させていただきます。 .slice()は1次元コピーとの事で新しい知識が得られて大変参考になったのですが、 その仕様であれば、例えばarray.sortは二次元配列の破壊的処理ですが、.slice()で破壊されなくなったりしますし、 LibraryReplaceFt()内に関しても var a = arr.slice();  //こちらは2次元コピーなので共有状態だから無駄な処理 a[b][col] = String(a[b][col]).replace(from,to).slice(); //こちらは一次元での処理なので大丈夫そう? のような気がするのですが、これらの違いは何なのでしょうか? 教えていただけると幸いです。
maisumakun

2020/05/27 23:37

array.sortの場合、2次元目は読むだけで変更しないので、(要素が共有状態のままでいいなら)1次元だけのコピーで問題なく動作します。
takaD

2020/05/27 23:43

早速の返答ありがとうございます。 なるほど、勉強になりました。 要素全体の並び替えと、要素単体の加工は切り離して考える必要があるのですね。 JSONに関して勉強してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問