Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to array.includes() in google apps script?

I'm using range.getValues() to load an array in Google Apps Script.

var array = SpreadsheetApp.getActive().getActivesheet().getRange('E10:E30').getValues();
> array = [["val1"],["val2"],["val3"],["val4"]]

I then want to loop through a separate list to see whether its elements exist in the array, using array.prototype.includes():

if(array.includes("val4")) {doSomething;}

Using array.prototype.includes() like this does not work for two reasons: 1) since each element in array is an array in itself and 2) because the method isn't available in Google Apps Script:

TypeError: Cannot find function includes in object

Then wanted to use array.prototype.flat() to solve 1) but it seems it isn't available in Google Apps Script either. I get the following error:

TypeError: Cannot find function flat in object

This is something I could do using brute force, but surely there's a neat way of doing it?

like image 951
a-burge Avatar asked Aug 09 '18 11:08

a-burge


1 Answers

EDIT(2019-04-07): Please be advised. With the expected V8 upgrade (ECMAScript 2017) for App Script, the language will natively support Array.prototype.includes and many other modern Javascript features in the near future.


The simplest solution for array.prototype.includes is to use the following polyfill from MDN in your apps script project. Just create a script file and paste the following code - the code/polyfill will add the function directly to the Array prototype object:

// https://tc39.github.io/ecma262/#sec-array.prototype.includes
if (!Array.prototype.includes) {
  Object.defineProperty(Array.prototype, 'includes', {
    value: function(searchElement, fromIndex) {

      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      // 1. Let O be ? ToObject(this value).
      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If len is 0, return false.
      if (len === 0) {
        return false;
      }

      // 4. Let n be ? ToInteger(fromIndex).
      //    (If fromIndex is undefined, this step produces the value 0.)
      var n = fromIndex | 0;

      // 5. If n ≥ 0, then
      //  a. Let k be n.
      // 6. Else n < 0,
      //  a. Let k be len + n.
      //  b. If k < 0, let k be 0.
      var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

      function sameValueZero(x, y) {
        return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
      }

      // 7. Repeat, while k < len
      while (k < len) {
        // a. Let elementK be the result of ? Get(O, ! ToString(k)).
        // b. If SameValueZero(searchElement, elementK) is true, return true.
        if (sameValueZero(o[k], searchElement)) {
          return true;
        }
        // c. Increase k by 1. 
        k++;
      }

      // 8. Return false
      return false;
    }
  });
}

For array.prototype.flat the MDN site also provides alternative solutions. One of which leverages array.prototype.reduce and array.prototype.concat:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat#Alternative

like image 114
TheAddonDepot Avatar answered Sep 19 '22 21:09

TheAddonDepot