Google apps script google应用程序脚本中的array.includes()的替代方案?

Google apps script google应用程序脚本中的array.includes()的替代方案?,google-apps-script,google-sheets,Google Apps Script,Google Sheets,我正在使用range.getValues()在谷歌应用程序脚本中加载一个数组 var array = SpreadsheetApp.getActive().getActivesheet().getRange('E10:E30').getValues(); > array = [["val1"],["val2"],["val3"],["val4"]] 然后,我想使用array.prototype.includes()遍历一个单独的列表,查看其元素是否存在于数组中: 这样使用不起作用有两个原

我正在使用
range.getValues()
在谷歌应用程序脚本中加载一个数组

var array = SpreadsheetApp.getActive().getActivesheet().getRange('E10:E30').getValues();
> array = [["val1"],["val2"],["val3"],["val4"]]
然后,我想使用array.prototype.includes()遍历一个单独的列表,查看其元素是否存在于数组中:

这样使用不起作用有两个原因:1)因为
array
中的每个元素本身就是一个数组;2)因为该方法在Google Apps脚本中不可用:

TypeError:找不到对象中包含的函数

然后想用它来解1)但似乎是这样。我得到以下错误:

TypeError:在对象中找不到函数平面

这是我可以用蛮力做的事情,但肯定有一种简洁的方法可以做到吗?

使用了
if(array.indexOf(“val4”)>-1{doSomething}如评论中所建议


我首先决定:

但正如下面提到的,箭头函数在谷歌应用程序脚本中不起作用


但在寻找答案的过程中,我发现了解决1)

function flatten(arrayOfArrays){
  return [].concat.apply([], arrayOfArrays);
}
肯定比我能想到的要好。

编辑(2019-04-07):请注意。随着AppScript预期的V8升级(ECMAScript 2017),该语言将在不久的将来原生支持和许多其他现代Javascript功能


最简单的解决方案是在应用程序脚本项目中使用以下内容。只需创建一个脚本文件并粘贴以下代码-代码/polyfill将直接将函数添加到Array prototype对象:

// 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;
    }
  });
}
//https://tc39.github.io/ecma262/#sec-array.prototype.includes
if(!Array.prototype.includes){
Object.defineProperty(Array.prototype,'includes'{
值:函数(searchElement,fromIndex){
if(this==null){
抛出新的TypeError(“'this'为null或未定义”);
}
//1.设O为?ToObject(该值)。
var o=对象(此);
//2.设len为?ToLength(?Get(O,“length”))。
var len=o.length>>>0;
//3.如果len为0,则返回false。
如果(len==0){
返回false;
}
//4.设n为?ToInteger(fromIndex)。
//(如果未定义fromIndex,此步骤将生成值0。)
var n=fromIndex | 0;
//5.如果n≥ 0,那么
//让k为n。
//6.否则n<0,
//让k是len+n。
//b.如果k<0,则k为0。
var k=Math.max(n>=0?n:len-Math.abs(n),0);
函数sameValueZero(x,y){
返回x==y | |(x的类型=='number'&y的类型=='number'&isNaN(x)&isNaN(y));
}
//7.当k

对于MDN,站点还提供了替代解决方案。其中之一利用和:


.includes()
替换为
.indexOf()+1
(如果元素不存在,它将产生
0
,否则它将产生一个介于1和数组长度之间的整数)。它在谷歌脚本中工作

if(array.indexOf("val4")+1) {doSomething;}

没有。我刚刚发现,但我认为我已经做到了:(谢谢你的帮助!array.some是存在的东西之一,但像我这样的人不会想到。虽然箭头函数不受支持,但你可以使用普通的函数定义…
arr.filter(函数(e,I,a){…
True@tehhowch,对于我来说,现在在arrow和normal之间的转换太过陡峭了一步(即,没有足够的时间搜索和理解),我不知道polyfill。我感觉我将是那里的常客。Thanks@a-burge不会持续很长时间(至少在涉及多填料的情况下)…谷歌计划升级应用程序脚本,以使用Chrome的V8引擎,该引擎完全支持EcmaScript 2017:)此外,您可以轻松地将polyfill代码粘贴到单独的文件中,而无需担心将其导入主代码。我经常有一个“polyfill.gs”在我的GAS项目中存档。@TheMaster没有什么具体的东西。但是声称升级已经测试了大约一年。我祈求在谷歌2019年发布一个版本。我明白了……所以在接下来的几天里,
包括和
索引的
并不是很容易互换的——一个返回布尔值,另一个返回一个间隔[-1,inf]上的n个整数。您还必须更改调用站点上的使用逻辑。在本例中,它实际上是可互换的(非常简单!)。消费逻辑一点也不需要改变。不过,感谢您解释您-1考虑代码片段行为差异的原因如下:
[“val4”,“foo”]
vs
[“foo”,“val4”]
vs
[“foo”,“bar”]
我看到了,
indexOf()的结果
需要向上移动一个单位,以说明
(0==false)==true
已更正。
// 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;
    }
  });
}
if(array.indexOf("val4")+1) {doSomething;}