【问题标题】:Filter Array by Another Array Compare the Rows for Column A and C Matches, Keep only Non-Matches Google Apps Script [Updated]按另一个数组过滤数组比较列 A 和 C 匹配的行,只保留不匹配的 Google Apps 脚本 [更新]
【发布时间】:2021-03-14 07:35:10
【问题描述】:

*编辑,我能够返回与我想要的相反的代码,代码如下。 更新了我尝试过的其他内容。我重写了一个包含测试数据的独立版本,因此您可以自己测试/查看 Logger 结果。

我想创建一个函数,它逐行比较两个数组 bLFinal 和 matchFinal。如果 bLFinal 中有一行与 matchFinal 中的行具有相同的 A 列和 C 列值,我想将其从 bLfinal 中删除。那么所有没有匹配的都是唯一剩下的。

这是我希望代码如何工作的示例。在下面的示例中,要过滤的数组 (bLFinal) 为 11 行,结果版本的 bLFinal 应为 7 行。

当 bLFinal 中的任何行匹配 matchFinal 中的任何行时,仅比较两个数组的 A 和 C 值(例如“penny”和“@FOX”),它会从 bLFinal 中删除匹配的行。

在我的实际用例中,我不一定知道 Col A 或 Col C 中到底是什么。所以我不能只将它们添加到代码中的列表中进行过滤。

//bLFinal array before filtering
[
["penny", "Up", "@FOX", "45"],
["shanice", "Up", "@FOX", "45"],
["barbara", "Down", "@BEAR", "22"],
["darell", "Down", "@SHARK", "10"],
["penny", "Up", "@BUNNY", "20"],
["jules", "Up", "@FOX", "45"],
["macy", "Up", "@FOX", "45"],
["terry", "Down", "@BEAR", "22"],
["shanice", "Down", "@SHARK", "10"],
["shanice", "Up", "@BEAR", "22"],
["kelly", "Up", "@BUNNY", "20"]
]
//matchFinal array to use to check bLFinal against

[
["george", "Down", "@FOX", "45"],
["shanice", "Up", "@FOX", "45"],
["barbara", "Up", "@BEAR", "22"],
["darell", "Up", "@SHARK", "10"],
["penny", "Up", "@BUNNY", "20"],
["carol", "Down", "@LIZARD", "70"],
["bernard", "Up", "@TOAD", "85"],
["bobby", "Up", "@BUNNY", "20"]
]
//Then, the resultant version of bLFinal should look like this:

[
["penny", "Up", "@FOX", "45"],
["jules", "Up", "@FOX", "45"],
["macy", "Up", "@FOX", "45"],
["terry", "Down", "@BEAR", "22"],
["shanice", "Down", "@SHARK", "10"],
["shanice", "Up", "@BEAR", "22"],
["kelly", "Up", "@BUNNY", "20"]
]

在我上面关于数组应该如何工作的内容中,以下行被删除/不包含在最终的 bLFinal 中,因为它们与 matchFinal 行的 col A 和 C 中的至少一个具有相同的 A 和 C 列。(如果 col B 或 D 不同,没有问题,我只想使用例如“shanice”和“@FOX”,col A 和 C 作为测试标准。

["shanice", "Up", "@FOX", "45"],
["barbara", "Down", "@BEAR", "22"],
["darell", "Down", "@SHARK", "10"],
["penny", "Up", "@BUNNY", "20"],

也就是说,因为具有 A col 和 C col 的行的值是 "shanice" 和 "@FOX"、"barbara" 和 "@BEAR"、"darell" 和 "@SHARK",最后是 "penny" 和 "@ BUNNY”在 matchFinal 的行中找到,它们应该从 bLFinal 中删除。 我想比较 bLFinal 中的任何/所有行以在 matchFinal 的任何行中查找 A 和 C 匹配项。


function bLow(){

var matchArray = [["george", "Down", "@FOX", "45"],
["shanice", "Up", "@FOX", "45"],
["barbara", "Up", "@BEAR", "22"],
["darell", "Up", "@SHARK", "10"],
["penny", "Up", "@BUNNY", "20"],
["carol", "Down", "@LIZARD", "70"],
["bernard", "Up", "@TOAD", "85"],
["bobby", "Up", "@BUNNY", "20"]];

var matchFinal = matchArray;
var matchLRow = matchArray.length;

Logger.log(matchArray.length);

var bLArray = [
["penny", "Up", "@FOX", "45"],
["shanice", "Up", "@FOX", "45"],
["barbara", "Down", "@BEAR", "22"],
["darell", "Down", "@SHARK", "10"],
["penny", "Up", "@BUNNY", "20"],
["jules", "Up", "@FOX", "45"],
["macy", "Up", "@FOX", "45"],
["terry", "Down", "@BEAR", "22"],
["shanice", "Down", "@SHARK", "10"],
["shanice", "Up", "@BEAR", "22"],
["kelly", "Up", "@BUNNY", "20"]
];

var bLFinal = bLArray;
var bLLrow = bLArray.length;

Logger.log(bLArray.length);

// This is where I'm having trouble. 
// It returns the same values for both before and after filtering of bLFinal which means it is not working.
// However, I want it to remove the 4 matching lines.

bLFinal.forEach(function(row, index){
 for (i=0 ; i<bLLrow ; i++){
   for (j=0 ; j<matchLRow ; j++){
  if (index !== 0){
    if(row[i][0] !== matchFinal[j][0] && row[i][2] !== matchFinal[j][2]){
      return;
    }
  }
   }
 } 
});
Logger.log(bLFinal.length); 
}

作为更新,我能够使用以下代码自行返回重复项

for (i=0 ; i<bLLrow ; i++){
   for (j=0 ; j<matchLRow ; j++){
     if(bLFinal[i][0] == matchFinal[j][0] && bLFinal[i][2] == matchFinal[j][2]){
      filteredBLArray.push(bLFinal[i]);
   } 
 }
 }

我现在正试图返回相反的,非重复的。

【问题讨论】:

    标签: javascript arrays google-apps-script


    【解决方案1】:

    我自己能弄明白。我正在回答我的问题,以便任何试图做相同或类似事情的人都可以使用它或至少将自己指向正确的方向。希望其他人也可以提供其他答案/方法。

    正如我上面更新的那样,我能够使用以下代码更改我的 for 循环以获取重复项(4 行数组),这帮助我改变了我的方法:

    for (i=0 ; i<bLLrow ; i++){
       for (j=0 ; j<matchLRow ; j++){
         if(bLFinal[i][0] == matchFinal[j][0] && bLFinal[i][2] == matchFinal[j][2]){
          filteredBLArray.push(bLFinal[i]);
       } 
     }
     }
    

    这为我指明了正确的方向,现在寻找从数组中删除元素的方法。 我发现了以下stackoverflow问题,它帮助我弄清楚如何通过向后迭代来删除项目(因为pop等在上面不起作用,因为它弄乱了数组大小) https://stackoverflow.com/a/28122081/12244743

    因此,抓取所有 7 个非重复项的更正 for 循环是这样的:

    for (i= bLFinal.length - 1 ; i>=0 ; i--){
      for (j= matchFinal.length - 1 ; j>=0 ; j--){
         if(bLFinal[i][0] == matchFinal[j][0] && bLFinal[i][2] == matchFinal[j][2]){
          bLFinal.splice(i,1);
     }
       } 
     }
      
    

    (如果您的数组中有要排除的标题文本(在第 1 行),则 i 和 j 可以设置为 >= 1。

    这是完整的工作代码,它返回原始数组 bLFinal 减去与 matchFinal 的行重复的 col A 和 col C 行。

    function bLow(){
    
    var matchArray = [["george", "Down", "@FOX", "45"],
    ["shanice", "Up", "@FOX", "45"],
    ["barbara", "Up", "@BEAR", "22"],
    ["darell", "Up", "@SHARK", "10"],
    ["penny", "Up", "@BUNNY", "20"],
    ["carol", "Down", "@LIZARD", "70"],
    ["bernard", "Up", "@TOAD", "85"],
    ["bobby", "Up", "@BUNNY", "20"]];
    
    var matchFinal = matchArray;
    var matchLRow = matchArray.length;
    
    Logger.log(matchArray.length);
    
    var bLArray = [
    ["penny", "Up", "@FOX", "45"],
    ["shanice", "Up", "@FOX", "45"],
    ["barbara", "Down", "@BEAR", "22"],
    ["darell", "Down", "@SHARK", "10"],
    ["penny", "Up", "@BUNNY", "20"],
    ["jules", "Up", "@FOX", "45"],
    ["macy", "Up", "@FOX", "45"],
    ["terry", "Down", "@BEAR", "22"],
    ["shanice", "Down", "@SHARK", "10"],
    ["shanice", "Up", "@BEAR", "22"],
    ["kelly", "Up", "@BUNNY", "20"]
    ];
    
    var bLFinal = bLArray;
    var bLLrow = bLArray.length;
    
    Logger.log(bLArray.length);
    var filteredBLArray = [];
    
    
    for (i= bLFinal.length - 1 ; i>=0 ; i--){
      for (j= matchFinal.length - 1 ; j>=0 ; j--){
         if(bLFinal[i][0] == matchFinal[j][0] && bLFinal[i][2] == matchFinal[j][2]){
          bLFinal.splice(i,1);
     }
       } 
     }
      
    
    Logger.log(bLFinal);
    Logger.log(bLFinal.length);
    }
    

    【讨论】:

    • 接受了我自己的答案,因为其他建议的答案(使用 .maps)对我来说运行速度较慢。
    【解决方案2】:

    blFinal 中在 matchFinal 的 A 列和 C 列中没有相同值的每一行

    function bLow() {   
      const matchFinal = [["george", "Down", "@FOX", "45"], ["shanice", "Up", "@FOX", "45"], ["barbara", "Up", "@BEAR", "22"], ["darell", "Up", "@SHARK", "10"], ["penny", "Up", "@BUNNY", "20"], ["carol", "Down", "@LIZARD", "70"], ["bernard", "Up", "@TOAD", "85"], ["bobby", "Up", "@BUNNY", "20"]];
      let bLFinal = [["penny", "Up", "@FOX", "45"], ["shanice", "Up", "@FOX", "45"], ["barbara", "Down", "@BEAR", "22"], ["darell", "Down", "@SHARK", "10"], ["penny", "Up", "@BUNNY", "20"], ["jules", "Up", "@FOX", "45"], ["macy", "Up", "@FOX", "45"], ["terry", "Down", "@BEAR", "22"], ["shanice", "Down", "@SHARK", "10"], ["shanice", "Up", "@BEAR", "22"], ["kelly", "Up", "@BUNNY", "20"]];
      let cA = matchFinal.map((r) => {
        return r[0] + r[2];
      });
      let oA = [];
      bLFinal.forEach(function (r) {
        if (!cA.includes(r[0] + r[2]))
          oA.push(r);
      });
      Logger.log(oA);
    }
    
    Execution log
    4:35:43 PM  Notice  Execution started
    4:35:44 PM  Info    [[penny, Up, @FOX, 45], [jules, Up, @FOX, 45], [macy, Up, @FOX, 45], [terry, Down, @BEAR, 22], [shanice, Down, @SHARK, 10], [shanice, Up, @BEAR, 22], [kelly, Up, @BUNNY, 20]]
    4:35:44 PM  Notice  Execution completed
    

    【讨论】:

    • 我想比较两个数组 bLFinal 和 matchFinal。如果 bLFinal 中有一行与 matchFinal 中的行具有相同的 A 列和 C 列值,我想删除它。那么所有没有匹配的都是唯一剩下的。
    • 感谢您的评论@Cooper。正如您所建议的,我已将我的脚本编辑并重写为一个可测试的版本,该版本仅包含有问题的问题。你介意再看看吗?
    猜你喜欢
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多