【问题标题】:How do I improve the performance of this matrix search function?如何提高此矩阵搜索功能的性能?
【发布时间】:2020-12-24 13:24:30
【问题描述】:

我有代表分类级别的表格形式的数据。每张纸上的列是给定(门、类、顺序等)的成员,其名称是列标题。

标题是订单,列内容是该订单中的家庭。 我有这个搜索功能,可以搜索给定家庭的订单表,并返回该家庭所属的订单。但是速度很慢。

我可以改进这个搜索算法,或者我的搜索方法来更快地在另一个工作表的多个单元格中运行这个函数吗?此工作簿包含参考表和一个示例 Foray 表,其中显示了我希望显着提高性能的功能。

https://docs.google.com/spreadsheets/d/1HvDpgWd6vhAF9UPiomwpmRLnzlduPU9c2ueWRwq3oZw/edit?usp=sharing

function findvalue(sheetName, searchVal) {
  if(searchVal.length === 0){
      throw 'Error. Incertae sedis.';
  };
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  var rangeData = sheet.getDataRange();
  var lastColumn = rangeData.getLastColumn();
  var lastRow = rangeData.getLastRow();
  var searchRange = sheet.getRange(1,1, lastRow-1, lastColumn-1);
  // Get array of values in the search Range
  var rangeValues = searchRange.getValues();
  // Loop through array and if condition met
  for ( i = 0; i < lastColumn - 1; i++){
    for ( j = 0 ; j < lastRow - 1; j++){
      if(rangeValues[j][i] === searchVal){
        return rangeValues[0][i]
      };
    };
  };
};

【问题讨论】:

  • 我怀疑你所做的是最快的。但您可能有兴趣尝试 textfinder。

标签: performance google-apps-script google-sheets query-optimization


【解决方案1】:

我相信你的目标如下。

  • 您希望降低用作自定义函数的脚本的处理成本。

修改点:

  • 看了你分享的Spreadsheet,发现findvalue的很多自定义函数都用在Example Foray的表格里。并且,例如,当看到单元格“K3”时,使用=iferror(findvalue("Phylum", J28), iferror(findvalue("Phylum", I28), iferror(findvalue("Phylum", H28), iferror(findvalue("Phylum", G28), iferror(findvalue("Phylum", F28), iferror(findvalue("Phylum", E28), iferror(findvalue("Phylum", D28), ""))))))) 的公式。似乎在单元格中使用了这样的公式。
    • 我认为这可能是您的问题的原因。
  • 为了减少脚本的处理成本,我想建议使用一个自定义函数来放置所有值。在您共享的电子表格中,单元格“E3:K58”的值由一个自定义函数输入。我认为这样可以降低工艺成本。

当单元格“E3:K58”的值由一个自定义函数放置时,脚本如下。

示例脚本:

请将以下脚本复制并粘贴到电子表格的脚本编辑器中,并保存。

function findvalues(sheetNames, searchValues) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const ar = sheetNames[0].map(name => {
    const values = ss.getSheetByName(name).getDataRange().getValues();
    const obj = values[0].reduce((o, _, i) => {
      const [v, ...k] = values.reduce((ar, r) => {
        if (r[i]) ar.push(r[i]);
        return ar;
      }, []);
      k.forEach(kk => o[kk] = v);
      return o
    }, {});
    return searchValues.map(sv => {
      let temp = "";
      for (let j = 0; j < sv.length; j++) {
        if (obj[sv[j]]) {
          temp = obj[sv[j]];
          break;
        }
      }
      if (temp) sv.push(temp);
      return temp;
    });
  });
  return ar[0].map((_, i) => ar.map(r => r[i]));
}
  • 为了使用此脚本,当您使用共享电子表格时,请执行以下流程。
    1. 清除工作表“Example Foray”的“E3:K58”单元格。
    2. =findvalues(E2:K2,D3:D58) 的公式放入工作表“Example Foray”的单元格“E3”中。
      • 从您的脚本和电子表格中,我了解到“E2:K2”和“D3:D58”的值分别是工作表名称和搜索值。
      • 为了降低循环开销,我分别用E2:K2D3:D58代替了E2:2D3:D

通过这种方式,值被放入单元格“E3:K58”中。

结果:

当上述脚本作为自定义函数使用时,变为如下。这些值与使用 findvalue 的电子表格相同。

注意:

  • 此示例脚本适用于共享电子表格中的“Example Foray”工作表。更改单元格结构时,可能无法使用脚本。所以,请注意这一点。

参考资料:

【讨论】:

    猜你喜欢
    • 2017-01-31
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 2021-11-22
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多