首页 > 解决方案 > 将数组与数组索引匹配时,代码未在最内层循环中执行 else 条件?

问题描述

  var amazon = activeSpreadsheet.getSheetByName('Amazon');
  var lastRow1 = amazon.getLastRow();
  var array1 = amazon.getRange('A2:A' + lastRow1).getValues();

  var source = activeSpreadsheet.getSheetByName('ProductDetails');
  var lastRow2 = source.getLastRow();
  var array2 = source.getRange('B2:B' + lastRow2).getValues();

  n = 2;
  x = 0; // match
  z = 0; // non-match

  for (var i = 0; i < array2.length; i++){
    for (var j = 0; j < array1.length; j++){

      if (array2[i] !== array1[j]){
        z = z + 1;
      }
      else {
        x = 9999
      }
    }
    newsheet.getRange([n],[5]).setValue(z);
    newsheet.getRange([n],[6]).setValue(x);
    if (z > x) {
      newsheet.getRange([n],[1]).setValue(array2[i]);
      n == n++;
      z = 0;
      x = 0;
      }
    else if (z < x) {
      z = 0;
      x = 0;
    }
}

我的项目是用 GAS(谷歌应用程序脚本)编写的,从本质上讲,出于所有意图和目的,JS 库中都有变化。

基本上我正在获取array2 中的一个元素并将它传递给一个循环以匹配array1。每次不匹配时,它加 1,当它匹配时(如果有任何匹配则只匹配一次),它存储一个任意大的数字(大于 array1 的长度)并比较它们。

正如你所看到的,我已经写出来显示这些值,我总是得到 z = 5183(array1 的长度)和 x = 0(意味着没有找到不匹配项)。因此,即使数组 2 和 1 中存在某些内容,它也会始终将其写入单元格。

应该发生的是,如果存在匹配,z= 5182 和 x= 9999(或任意大数)并且由于 5182 < 9999 它什么都不做。

我的范围错了吗?还是我没有正确编写 If/Else?或者是别的什么?

标签: arraysif-statementgoogle-apps-scriptmatch

解决方案


Array您的代码在两个s的元素之间执行严格的比较。没关系,一般来说。但是,对于那些特定Array的 s,这些元素也是Arrays,这意味着严格(不)相等正在检查它们是否是内存中完全相同的数组对象。有关更多信息,请参阅此问题

您可能想要进行基于值的比较,这意味着您需要比较该内部数组的特定元素(即再次索引)。if (array2[i][0] !== array1[j][0]) {...}将检查内部数组的第一个元素。

array1查看and的实例化array2,我们看到这些确实是来自单列s 的二维数组Range,因此每个内部数组中只有 1 个元素。您可以通过在读取这些数组时展平这些数组来降低必要的索引级别:

const array1 = sheet.getRange(...).getValues().map(function (row) { return row[0]; });
const array2 = ...;

我也不确定你为什么要传入数组- 你应该以与 Apps 脚本文档中详述的方法签名Sheet#getRange一致的方式传入 1-4 个参数。

请注意,有更好的算法来检查给定数组中是否存在值 - 您重新扫描所有第二个数组以查找第一个数组的每个值。在提出有关如何改进算法的新问题之前,您应该对该主题进行彻底的研究。

最后,您应该实施使用批处理方法的最佳实践——您当前setValue在循环中调用。Range#setValues考虑将结果存储到数组中,然后在循环完成后写入。关于这个主题,您可以查看许多问题。


推荐阅读