I\'m trying to put together a function that will allow me to pull a column\'s info from one sheet to another based on a key column. This would work similar to an index match or
Slow script:
O(n2): For every element in array 1, the array 2 is iterated from top to bottom. Even after finding a match in array 2, the loop is not broken(break
), but the inner loop is completed until the end of the array2 unnecessarily.
getValues()
is requested twice for two columns of the same sheet. Contact with spreadsheet is costly. So, limiting it is necessary.
One possible solution to achieve O(n)
:
const ss = SpreadsheetApp.getActive();
/**
* @param {GoogleAppsScript.Spreadsheet.Sheet} fromSht -Sheet to import from
* @param {GoogleAppsScript.Spreadsheet.Sheet} toSht -Sheet to import to
* @param {Number} fromCompCol -Column number of fromSht to compare
* @param {Number} toCompCol -Column number of toSht to compare
* @param {Number} fromCol -Column number of fromSht to get result
* @param {Number} toCol -Column number of toSht to get result
*/
function vlookup_2(
fromSht = ss.getSheetByName('Sheet1'),
toSht = ss.getSheetByName('Sheet2'),
fromCompCol = 1,
toCompCol = 1,
fromCol = 2,
toCol = 2
) {
const toShtLr = toSht.getLastRow();
const toCompArr = toSht.getRange(2, toCompCol, toShtLr - 1, 1).getValues();
const fromArr = fromSht.getDataRange().getValues();
fromCompCol--;
fromCol--;
/*Create a hash object of fromSheet*/
const obj1 = fromArr.reduce((obj, row) => {
let el = row[fromCompCol];
el in obj ? null : (obj[el] = row[fromCol]);
return obj;
}, {});
//Paste to column
toSht
.getRange(2, toCol, toShtLr - 1, 1)
.setValues(toCompArr.map(row => (row[0] in obj1 ? [obj1[row[0]]] : [null])));
}