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

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

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

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

Google Apps Script

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

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

3111閲覧

GASでの1次元配列と2次元配列の判定方法。及び、空白を除外した配列の作成方法

takaD

総合スコア315

Google スプレッドシート

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

Google Apps Script

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

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

2クリップ

投稿2020/05/14 02:29

編集2020/05/14 02:29

前提・実現したいこと

自前のライブラリに汎用性のあるスクリプトを作成したいと思っています。

内容は、
A.1次元配列なら、配列内のにあるデータのみを抽出。
B.2次元配列かつ、1行しかなければ、1次元配列と同等の結果を出力する。
C.2次元配列なら、最初の行の配列内にあるデータを基準にデータを抽出する。
(仮に最初の行の一部の列で空白かつ、別の行で同列の場所にデータがあった場合は、気にせず消す)

発生している問題・エラーメッセージ

諸々問題なく作成できましたが、自分の考え方(プログラムの書き方)が何となく変で、
やろうとしている内容に対して、必要以上に行が長くなり、スマートでない気がしています。

気分的にはFilter()やmap()的なものを使えば上手くできそうな気はしても、知識と経験乏しく、
なにかしら手法や考え方があるならば、ご教授いただけると幸いです。

また、1次元配列と2次元配列の判定方法は、
if(data[0][1] == null)
で正しいのでしょうか?
こちらも、何となく無理やりやってる気がして気になっております。

もし回答いただいた場合大変失礼になりますが、
いろいろな考え方があるかもしれませんので、
ベストアンサーのほうは数日たってからやろうと思います。

該当のソースコード

GAS

1function test(){ 2 3 var data1 = ["1","","","b","a","4","","e","","","","a","","",""]; 4 //スクリプト等で作成した場合の配列(1次) 5 var log = arrayBlankFilter(data1); 6 Logger.log(log); 7 //求める出力:[1, b, a, 4, e, a] 8 9 10 11 var data2 = [["No.","名前","備考","","","項目1","項目2","項目3","",""]] 12 //getValues()で作成した場合の、気分的には一次配列データ(実際は2次元配列) 13 var log = arrayBlankFilter(data2); 14 Logger.log(log); 15 //求める出力:[[No., 名前, 備考, 項目1, 項目2, 項目3]] 16 17 18 19 var data3 = [ 20 ["No.","名前","備考","","","項目1","項目2","項目3","",""], 21 ["1" ,"AAA","" ,"","","1" ,"5" ,"" ,"",""], 22 ["2" ,"ABA","BAA" ,"","","" ,"2" ,"" ,"",""], 23 ["3" ,"ACA","" ,"","","" ,"4" ,"2" ,"",""], 24 ["4" ,"ADA","BAC" ,"2","","1" ,"" ,"1" ,"a",""], 25 ] 26 //getValues()で作成した配列(2次元配列) 27 var log = arrayBlankFilter(data3); 28 Logger.log(log); 29 /*求める出力:[ 30 [No., 名前, 備考, 項目1, 項目2, 項目3], 31 [1 , AAA, , 1 , 5 , ], 32 [2 , ABA, BAA , , 2 , ], 33 [3 , ACA, , , 4 , 2 ], 34 [4 , ADA, BAC , 1 , , 1 ] 35 ] 36 */ 37 38 } 39 40 function arrayBlankFilter(data){ 41 var arr = []; 42 43 if(data[0][1] == null)//1次配列であれば、data[0][1]は存在しない 44 { 45 for(let i in data) 46 { 47 if(data[i] != "") 48 { 49 arr.push(data[i]); 50 } 51 } 52 }else 53 { 54 for(let i in data) //最初に格納スペースを生成しないとエラーになる 55 { 56 arr.push([]) 57 } 58 for(let i in data[0]) 59 { 60 if(data[0][i] != "") 61 { 62 for(let j in data) 63 { 64 arr[j].push(data[j][i]);//列の最初にデータがあれば縦方向にデータを構築していく 65 } 66 } 67 } 68 } 69 return arr 70 }

補足情報(FW/ツールのバージョンなど)

Chrome V8ランタイム

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

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

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

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

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

guest

回答2

0

ベストアンサー

それぞれ用途が違うのに無理に一つの関数にまとめるのは可読性が落ちるのでやめたほうがいいと思います。

私だったらそれぞれこう書きます。

JavaScript

1const data1 = ["1","","","b","a","4","","e","","","","a","","",""]; 2//※厳密にチェックするなら value => value !== "" 3const result1 = data1.filter(value => value); 4console.log(JSON.stringify(result1)); 5//求める出力:[1, b, a, 4, e, a]

2は結局3のパターンの一種なのでまとめてこんな感じの処理を関数化でrしょうか。

JavaScript

1const data3 = [ 2 ["No.", "名前", "備考", "", "", "項目1", "項目2", "項目3", "", ""], 3 ["1", "AAA", "", "", "", "1", "5", "", "", ""], 4 ["2", "ABA", "BAA", "", "", "", "2", "", "", ""], 5 ["3", "ACA", "", "", "", "", "4", "2", "", ""], 6 ["4", "ADA", "BAC", "2", "", "1", "", "1", "a", ""], 7]; 8//getValues()で作成した配列(2次元配列) 9//ヘッダー行から必要なカラムのインデックスの配列を作成する 10const headerColumns = data3[0] 11 .map((value, index) => ({ value, index })) 12 .filter(item => item.value) 13 .map(item => item.index); 14//データから必要なカラムのインデックスの列だけにフィルタ 15const result3 = data3.map((row) => 16 row.filter((_, index) => headerColumns.indexOf(index) !== -1) 17); 18 19console.log(JSON.stringify(result3)); 20

投稿2020/05/14 06:54

draq

総合スコア2573

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

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

takaD

2020/05/15 01:12

回答ありがとうございます。 やはり可読性を考えると、そもそも一次配列と二次配列を識別して処理を振り分けるという発想から考え直した方がいいのですかね・・・ headerColumnsのほうもありがとうございました。 なぜこれで動くのか含め、勉強させていただきます。
guest

0

変数名、関数名がしっくり来てませんが…

再帰とクロージャーでdata1,2,3を共通で処理します。

js

1var data1 = ["1","","","b","a","4","","e","","","","a","","",""]; 2//求める出力:[1, b, a, 4, e, a] 3 4var data2 = [["No.","名前","備考","","","項目1","項目2","項目3","",""]] 5//求める出力:[[No., 名前, 備考, 項目1, 項目2, 項目3]] 6 7var data3 = [ 8 ["No.","名前","備考","","","項目1","項目2","項目3","",""], 9 ["1" ,"AAA","" ,"","","1" ,"5" ,"" ,"",""], 10 ["2" ,"ABA","BAA" ,"","","" ,"2" ,"" ,"",""], 11 ["3" ,"ACA","" ,"","","" ,"4" ,"2" ,"",""], 12 ["4" ,"ADA","BAC" ,"2","","1" ,"" ,"1" ,"a",""], 13 ] 14 /*求める出力:[ 15 [No., 名前, 備考, 項目1, 項目2, 項目3], 16 [1 , AAA, , 1 , 5 , ], 17 [2 , ABA, BAA , , 2 , ], 18 [3 , ACA, , , 4 , 2 ], 19 [4 , ADA, BAC , 1 , , 1 ] 20 ] 21 */ 22 23//Filterする元ネタをクロージャーで保持…もっといい実装が有るかも 24const isFilterArray = (arr = []) => { 25 const result = arr.map((v, i) => v !== "" ? true : false); //arrの各項で、””の場合はfalse(Filter対象外)にする 26 const isFilterArrayClosure = () => { 27 return (result); 28 } 29 return (isFilterArrayClosure); 30} 31 32const filterArray = (arr, isFilter = () => { return ([]) }) => { 33 if (!Array.isArray(arr[0])) { 34 if (isFilter().length === 0) {//1次元配列時、filterする元ネタを作る 35 isFilter = isFilterArray(arr); 36 } 37 return (arr.filter((v, i) => isFilter()[i])); 38 } else { //再帰して、2次元配列(正確には配列の配列)を1時がん配列として処理 39 return (arr.map((v, i) => { 40 if (i === 0) { //2次元配列時、最初の1次元配列を使って、filterする元ネタを作る 41 isFilter = isFilterArray(v); 42 } 43 return (filterArray(v, isFilter)); //1次元配列にばらして再帰 44 })) 45 } 46}; 47 48console.log('test', filterArray(data1)); 49console.log('test', filterArray(data2)); 50console.log('test', filterArray(data3)); 51 52

投稿2020/05/15 23:22

oikashinoa

総合スコア2826

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

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

takaD

2020/05/18 00:51

返答遅くなり申し訳ありません。 自分の今の知識では読み解けないレベルのコードで大変勉強になります。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問