Google Apps Scriptで重複しないレコードだけ取り出す【GAS】

時々、teratailなどのサイトを巡って、回答できそうな内容に回答してたりするのですが、現場ならではの質問や要望が出てきたりするので、とても参考になります。

さて、そんな中、データの塊に於いて、A列の記号が重複していないレコードだけを取り出すというテーマがあり、挑戦してみました。月間売上データの中であまり売れていないものだけを取り出すといったケースで使えそうです。

図:これが求める結果

よくある勘違い

通常、配列内で重複する値があった時に、ユニークな値を取り出すのには、配列.filterなどのメソッドを使ったり、ループ回してindexOfで調べるといった事があります。ただ、問題なのはこれ「ユニークな値として取り出す」のであって、「重複していない値を取り出す」わけじゃない点。

//配列
var array = [1,2,2,3,4,4,4,5,6,6,7,8,9]

//filterで取り出すと
array.filter(function (x, i, self) {
  return self.indexOf(x) === i;
});

//出てくる値は。。。2,4,6は必要ないのに・・・・
[1,2,3,4,5,6,7,8,9]

しかもこれは1次元配列で出来ることで、スプレッドシートのデータの塊である2次元配列でやるにはこのまま出来るわけじゃない。

必要なのは、[1,3,5,7,8,9]の値を取り出し、それを含むレコードだけを取り出すこと。

サンプルファイル

※メニューに出てくる🍄取り出し⇒非重複抽出を実行すると、E列にそのレコードが取り出される仕組みです

ソースコード

//実際に出力してみる
function hikaku(){
  //スプレッドシートのデータを取得する
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1");
  
  //シートデータを取得する
  var ss = sheet.getRange("A1:C6").getValues();
  
  //A列だけ取得する
  var array = sheet.getRange("A1:A6").getValues();

  //A列を1次元配列で取り出す
  const list = array.reduce((pre,current) => {pre.push(...current);return pre},[]);
  
  //重複要素だけ取り出す
  let result = list.filter(function(x, i, self) {
        return self.indexOf(x) !== i; 
  });
  
  //ssの塊から重複していないレコードだけ、配列に取り出す
  var singleman = [];
  
  for(var i = 0;i<ss.length;i++){
    //重複リストにいるかどうか判定
    var ret = result.includes(ss[i][0]);
    
    //falseの場合配列にレコード単位でpush
    if(ret == false){
      singleman.push(ss[i]);
    }
  }
  
  //スプレッドシートのE列辺りに出力
  var lastColumn = singleman[0].length;  //カラムの数を取得する
  var lastRow = singleman.length;      //行の数を取得する
  sheet.getRange(1,5,lastRow,lastColumn).setValues(singleman);  

}
  • スプレッドシートのデータの塊、A列だけの塊が必要なデータ群
  • A列だけの塊は1次元配列に変換(list)⇒重複してる要素だけ取り出す(result)
  • forループでスプレッドシートの塊を回し、A列の値をresultの塊に対してincludesで調査し、trueが返ってくれば重複、falseが返ってくれば対象のレコードとなります。
  • 最後に書き込み用配列にpushして、E列に書き込み
  • このコードはV8 Runtimeで動作します。
  • ユニークな値を取り出してるわけじゃないのがポイントです。
  • ret == trueで判定式を変更すれば重複するものだけを抽出も出来ます。便利!!

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)