如何在 google 应用脚本中比较它们之间的几行值

How to compare several rows of values between them on google app script

我有一个 google sheet 具有以下数据 google sheet "formatfruit"

每个用户都有一个水果和蔬菜相关联,我想知道每个用户在google sheet "formatfruit" 中的相似度百分比 今天我可以将第一个用户 kevin 与其他所有用户进行比较 return 他与另一个 google sheet 名为“matchofruit”的相似度百分比。

当用户与凯文有共同的水果或蔬菜时,我关联值“1”,如果用户没有共同的水果或蔬菜,则关联值“0”。 googlesheetmatchofruit中出现的结果在这里 google sheet matchofruit

我使用的代码如下

function myFunction() {
  var formafruit = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("fruit");
  var matchofruit = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("matchofruit");
  
  var n = formafruit.getLastRow(); 
  var user1 = formafruit.getRange(2,1).getValues();// name user 1 : kévin
  var user2 = formafruit.getRange(3,1).getValues();// name user 2 : mikael

    for (var i = 2;i<4;i++) { // i<4 because we have 3 column in formafruit
      for (var z = 2;z<n+1;z++) {
    matchofruit.getRange(z,1).setValue(user1); // Return the name of the users in the first column
    if(formafruit.getRange(2,i).getValue() === formafruit.getRange(z,i).getValue()){ // Compare the fruits and vegetables associated to kévin with the fruits and vegetables associated to each user
    matchofruit.getRange(z,i).setValue(1); // Returns 1 if kevin shares at least one fruit or vegetable in common with a user
      }
    else {
    matchofruit.getRange(z,i).setValue(0);
      } 
    }
  }
  
  // Calculate the % of common values
    for (var p = 0;p<n-1;p++){}
    for (var s = 0;s<n-1;s++) {
    var scoreforall = matchofruit.getRange(2,2,p,11).getValues()[s]// get the array of all the matches
    let sum = 0;
    for (let e = 0; e < scoreforall.length; e++) {
    sum += scoreforall[e]; // add each array together
    }
    var sumTotal= Math.round(sum*(100/2)); // convert in percentage each sum 
    matchofruit.getRange(s+2,4).setValue(sumTotal); //  send match values in column 4
   } 

  // Return the result in a sentence
    for (var a = 2;a<n+1;a++) {
    var usern = formafruit.getRange(a,1).getValues(); //get all the users' emails in the formafruit
    var valeurmatch = matchofruit.getRange (a,4).getValues(); // get value % of matches
    matchofruit.getRange(a,5).setValue(user1+" "+"have"+" "+valeurmatch+"%"+" "+"of values in common with"+" "+usern);//Return the % of common value between Kevin and the other users
    }    
    
}

我希望能够为 mikael、gauthier、vanessa 和 mireille 做同样的事情,因为我知道我只放了 5 个用户来简化问题,但实际上可以有 100 多个用户,而且每个用户都有超过 11 个关联值(这里我们只有 2 种不同类型的值,水果和蔬菜)。几个星期以来,我一直在寻找解决问题的方法,但我还没有找到任何解决方法。你有什么想法吗?

谢谢!

我相信你的目标如下。

  • 您想实现以下几种情况。 (以下图片来自OP的问题。)

    • 来自

  • 以你的情况为例,当使用5个用户时,你想创建25行。

当我看到你的脚本时,循环中使用了setValuesgetValues的方法。我认为这变成了高处理成本。 Ref所以,我想提出以下修改。

修改后的脚本:

function myFunction2() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const [src, dst] = ["fruit", "matchofruit"].map(s => ss.getSheetByName(s));
  const [, ...values] = src.getDataRange().getValues();
  const res = values.flatMap(([a1, ...v1]) =>
    values.map(([a2, ...v2]) => {
      const temp = v1.map((e, i) => e == v2[i] ? 1 : 0);
      const sum = (temp.filter(f => f == 1).length / temp.length) * 100;
      const matchResult = `${a1} have ${sum}% of values in common with ${a2}`;
      return [a1, ...temp, sum, matchResult];
    })
  );
  dst.getRange(2, 1, res.length, res[0].length).setValues(res);
}
  • 在此修改中,值是从“水果”sheet 中检索的。并且,创建了一个用于放入“matchofruit”sheet 的数组。然后,将创建的数组放入“matchofruit”sheet.

注:

  • 在此示例脚本中,“matchofruit”的 header 行已被放置。如果您想将 header 行添加到“matchofruit”sheet,请将其添加到我建议的脚本中。

参考文献: