From 71323dfd9b79f5d43c20d7a938a3ac2c8996a55c Mon Sep 17 00:00:00 2001 From: Guillem Orpinell <35528026+urpizu@users.noreply.github.com> Date: Thu, 29 Nov 2018 16:18:17 +0100 Subject: [PATCH 1/4] Added getItemValuesById() --- utilities.gs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 utilities.gs diff --git a/utilities.gs b/utilities.gs new file mode 100644 index 0000000..a453317 --- /dev/null +++ b/utilities.gs @@ -0,0 +1,74 @@ +function getItemValuesById(sheetName, headerRow, indexField, id, isSorted) { + var sheet = SpreadsheetApp.getActive().getSheetByName(sheetName); + var numColumns = sheet.getLastColumn(); + var numRows = sheet.getLastRow(); + var header = sheet.getRange(headerRow, 1, 1, numColumns).getValues(); + var idColumnIndex = header[0].indexOf(indexField) + 1; + var ids = sheet.getRange(headerRow + 1, idColumnIndex, numRows - headerRow, 1).getValues(); + + var rowIndex = (isSorted)? ids.binaryIndexOf(id) : ids.indexOf2d(id); + if (rowIndex === -1) { + return undefined + } + var itemRow = sheet.getRange(rowIndex + headerRow + 1, 1, 1, numColumns).getValues(); + var item = {}; + for (var i = 0; i < itemRow[0].length; i++) { + var value = itemRow[0][i]; + var field = header[0][i]; + item[field] = value; + } + return item +} + +/** + * An indexOf search on a host 2d array. + * + * @param {*} searchElement The item to search for within the array. + * @param {Number} columnIndex The index where to search in the inner array (0 by default). + * @return {Number} The index of the element which defaults to -1 when not found. + */ +Array.prototype.indexOf2d = function(searchElement, columnIndex) { + if (!columnIndex) { + columnIndex = 0; + } + for (var i = 0; i < this.length; i++) { + if (this[i][columnIndex] === searchElement) { + return i; + } + } + return -1; +} + + +/** + * Performs a binary search on the host 2d array. + * + * @param {*} searchElement The item to search for within the array. + * @param {Number} columnIndex The index where to search in the inner array (0 by default). + * @return {Number} The index of the element which defaults to -1 when not found. + */ +Array.prototype.binaryIndexOf = function(searchElement, columnIndex) { + if (!columnIndex) { + columnIndex = 0; + } + var minIndex = 0; + var maxIndex = this.length - 1; + var currentIndex; + var currentElement; + + while (minIndex <= maxIndex) { + currentIndex = (minIndex + maxIndex) / 2 | 0; + currentElement = this[currentIndex][0]; + + if (currentElement < searchElement) { + minIndex = currentIndex + 1; + } + else if (currentElement > searchElement) { + maxIndex = currentIndex - 1; + } + else { + return currentIndex; + } + } + return -1; +} \ No newline at end of file From a77e1fd192afb68a2082eb332f9aa41862fd8421 Mon Sep 17 00:00:00 2001 From: Guillem Orpinell <35528026+urpizu@users.noreply.github.com> Date: Thu, 29 Nov 2018 16:24:34 +0100 Subject: [PATCH 2/4] Added breaklines at the end --- utilities.gs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utilities.gs b/utilities.gs index a453317..b56f822 100644 --- a/utilities.gs +++ b/utilities.gs @@ -71,4 +71,7 @@ Array.prototype.binaryIndexOf = function(searchElement, columnIndex) { } } return -1; -} \ No newline at end of file +} + + + From 403ac4791872b05c2755630f156abb8d93559f99 Mon Sep 17 00:00:00 2001 From: Guillem Orpinell <35528026+urpizu@users.noreply.github.com> Date: Mon, 3 Dec 2018 12:30:03 +0100 Subject: [PATCH 3/4] Bug fixed --- utilities.gs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities.gs b/utilities.gs index b56f822..a4e0e97 100644 --- a/utilities.gs +++ b/utilities.gs @@ -58,7 +58,7 @@ Array.prototype.binaryIndexOf = function(searchElement, columnIndex) { while (minIndex <= maxIndex) { currentIndex = (minIndex + maxIndex) / 2 | 0; - currentElement = this[currentIndex][0]; + currentElement = this[currentIndex][columnIndex]; if (currentElement < searchElement) { minIndex = currentIndex + 1; From 5ffa9b873d3c0841743d0ca323eb607c58e35e14 Mon Sep 17 00:00:00 2001 From: Guillem Orpinell <35528026+urpizu@users.noreply.github.com> Date: Mon, 7 Jan 2019 13:42:06 +0100 Subject: [PATCH 4/4] Documentation added --- utilities.gs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/utilities.gs b/utilities.gs index a4e0e97..c0877ae 100644 --- a/utilities.gs +++ b/utilities.gs @@ -1,4 +1,17 @@ -function getItemValuesById(sheetName, headerRow, indexField, id, isSorted) { +/** + * Use this function when you need to find item values in a table by index field. + * Unlike the original method getItemById, this function does not create a sheetfu table. + * It is a convenient alternative in large databases where the search performance is key. + * For example, look up a price of an automotive part by the part number. + * + * @param {String} sheetName: Name of the target sheet. + * @param {Number} headerRow: Row number where the header is. + * @param {String} indexField: Field name in header where you want to lookup the value. + * @param {*} lookupValue: Value you want to look up. + * @param {Boolean} isSorted: Whether the index field is sorted or not. + * @return {Object} An object item containing only values, where fields match the header values. + */ +function getItemValuesById(sheetName, headerRow, indexField, lookupValue, isSorted) { var sheet = SpreadsheetApp.getActive().getSheetByName(sheetName); var numColumns = sheet.getLastColumn(); var numRows = sheet.getLastRow(); @@ -6,7 +19,7 @@ function getItemValuesById(sheetName, headerRow, indexField, id, isSorted) { var idColumnIndex = header[0].indexOf(indexField) + 1; var ids = sheet.getRange(headerRow + 1, idColumnIndex, numRows - headerRow, 1).getValues(); - var rowIndex = (isSorted)? ids.binaryIndexOf(id) : ids.indexOf2d(id); + var rowIndex = (isSorted)? ids.binaryIndexOf(lookupValue) : ids.indexOf2d(lookupValue); if (rowIndex === -1) { return undefined }