見出し画像

【GAS】Google Apps Script 活用事例 filterメソッドを活用すると効率化の幅がどんどん広がる

だいぶ、mapやfilterの使い方もこなれてきて、いろいろな自動化を出来るようになってきました。その備忘録として残しておこうと思います。


filterメソッドで配列内の空白を削除する

function myFunction() {
 const array    = ['aaa', 'bbb', '', ''];
 const newArray = array.filter(value => value);

 //空白文字の削除に成功
 console.log(newArray); //[ 'aaa', 'bbb' ]
}

getRange()などで取得するも、空白行が存在する時によく使います。

const array = values.map(row => row[0]);

上記のように書くと空白行も含めて、縦1列を、1次元配列として取得できます。実務だとセルの結合によって、空白行があるケースがしばしば散見されるため、空白を省くと書き込む行がズレてしまう事があります。そのため、空白行を含めたまま1次元配列を残しています。

filterメソッドで値が含まれていない配列を削除する

function myFunction2(){
 const values    = [[],['aaaa', 'bbbbb', 'ccccc'],[]];
 
 //配列の要素数が0以上のものを残す
 const newValues = values.filter(array => 0 < array.length );
 console.log(newValues); //[ [ 'aaaa', 'bbbbb', 'ccccc' ] ]
}

どういう状況で使いたいなと思ったかは忘れましたが、値が含まれていない
1次元配列を削除したいと思ったことがありました。

function myFunction1(){
 const values    = [[],['aaaa', 'bbbbb', 'ccccc'],[]];
 const newArray = values.flat();

 //空白文字の削除に成功
 console.log(newArray); //['aaaa', 'bbbbb', 'ccccc']

}

値を含まれていない配列を削除して1次元配列を作成したい場合はflatが便利です。

filterメソッドで特定の値を含む行のみを残す

function myFunction3(){
 const values    = [[ 'ケータ', '小学5年生'],['ジバニャン', '猫'],['ウィスパー', '執事']];
 const newValues = values.filter(array => array.indexOf('小学5年生') !== -1);
 console.log(newValues); //[ [ 'ケータ', '小学5年生' ] ]
}

サンプルでは、小学5年生という単語を含む1次元配列のみを残して、2次元配列を作成します。手動でフィルターをかけた時と全く一緒の挙動です。実務では下記のような場合に便利です。

応募者IDと付き合わせて、当該シートに転記済みかどうかを判別する。

//JP5555の対象者の行のみ残して、管理表の最終行直下にペーストしたい。

//idArray 転記先の応募者IDの1次元配列    ['JP1111', 'JP2222', 'JP3333']
//values  採用媒体のCSVなど・・応募者情報 [['JP1111', '野比のび太'],['JP5555', 'スネ夫']]

const newValues = values.filter(row => idArray.indexOf(row[0]) === -1);
const lastRow   = sheet.getLastRow();

//新規の人がいない場合は転記を実施しない
if(0 < newValues.length){
 const range = sheet.getRange(lastRow, 1, newValues.length, newValues[0].length);
 console.log(`転記範囲: ${range.getA1Notation()}`);
 range.setValues(newValues);
}

スカウト媒体などCSV形式で取得可能な応募情報から、既にシートに転記済みかどうかをIDで判別して、該当しない  =  新規の応募者とみなして転記するといった具合です。

上記の例だと、JP5555 スネ夫が新着応募の学生と判断出来ます。
実務では新着応募があったら、列の最後尾に追加するといった自動化で使用しています。

配列内の重複を削除して、新しい配列を作成する


function myFunction4(){
 const array    = ['aaaa', 'bbbb', 'fffff', 'rrrrr', 'aaaa', 'rrrrrr', 'xxxxxxx', 'aaaa'];
 const newArray = Array.from(new Set(array));
 console.log(newArray);
 
 //[ 'aaaa', 'bbbb', 'fffff', 'rrrrr', 'rrrrrr', 'xxxxxxx' ]
}

厳密にはfilterではないのですが、'aaaa' が削除されて新しい配列が作られます。こちらのエントリーで使用しました。

配列内の重複のみを抽出する

function myFunction5(){
 const array    = ['aaaa', 'bbbb', 'fffff', 'rrrrr', 'aaaa', 'rrrrrr', 'xxxxxxx', 'aaaa'];
 const newArray = array.filter((value, index) => array.indexOf(value) !== index);
 console.log(newArray); //[ 'aaaa', 'aaaa' ]
}

過去にはこんな記事を書いています。

指定した単語が複数一致する行を取得する

function test_filterValues(){
  const values = [
    ['JP123', 'のび太', '2000/1/1', '男性'],
    ['JP456', 'スネ夫', '2000/1/1', '男性'],
    ['JP123', '静香', '1999/1/1', '女性'],
  ]

  const params   = ['男性', '2000'];
  const filtered = values.filter(row => params.every(param => row.join(',').includes(param)));
  console.log(filtered);

  return filtered

}
ログの出力

params.someを使うといずれかが一致した場合にすることができます。

処理に必要な列のみを抽出するスクリプト

/**
* getDataRange()などで取得した2次元配列から必要な列だけを抽出し、新しい2次元配列を作成する
* 
* @param  {object} 元の2次元配列
* @param  {object} 見出し行のオブジェクト (例)column = {id: 0, name: 1, university: 3}
* @param  {string} 2次元配列から情報を取捨選択するためのキーワード
* @return {object} 新しい配列
*
*/
function selectColumn(values, column, keyWord){
 const keys    = Object.keys(column);
 const numbers = keys.map(key => column[key]);

 console.log(numbers);//1次元配列

 //indexに該当する列だけを残して2次元配列を作成する
 const newValues = values.map(array => array.reduce((accumulator, current, index) =>{
     if(numbers.includes(index)){
       accumulator.push(current);
     }
   return accumulator
   }, [])//reduce
 );//map

 //console.log(newValues);
 
 if(!keyWord){
  //keyWordが省略されており、定義されていない場合、空白行を取り除く
   const filtered = newValues.filter(row => row[0] !== '');
   console.log(filtered);

   return filtered

 }else if(keyWord){
   //newValuesから、さらに特定の単語が含まれている配列のみを残す
   const filtered = newValues.filter(row => row.indexOf(keyWord) !== -1);

   console.log(filtered);
   return filtered
 }
}

1列目と2列目のみ抽出

function test_filterValues(){
  const values = [
    ['JP123', 'のび太', '2000/1/1', '男性'],
    ['JP456', 'スネ夫', '2000/1/1', '男性'],
    ['JP123', '静香', '1999/1/1', '女性'],
  ];

  const column   = {id: 0, name: 1};
  const filtered = selectColumns(values, column);

}
ログの出力結果




この記事が気に入ったらサポートをしてみませんか?