【问题标题】:Filter a 2D Array From Elements of Another从另一个元素中过滤二维数组
【发布时间】:2019-01-18 09:38:47
【问题描述】:

我有两组数值元素存储为二维数组。这些值是使用.getValues() 从列中获取的。一个是完整列表,另一个是部分列表。我想要一个返回完整列表减去部分列表的函数。

  • partialListArr 可能包含重复项。 fullListArr 确实 不是。
  • 我需要输出也是一个二维列表,因为它们将用于.setValues()
  • 值都是数字。

这是我尝试过的。

function myFunction() {
  var ss = SpreadsheetApp.getActive();
  var partialListArr = ss.getSheetByName('sheet 2').getRange(1,1,357,1).getValues();
  var fullListArr = ss.getSheetByName('sheet 1').getRange(1,1,942,1).getValues();

  var arr = fullListArr.filter(function(item){
    return partialListArr.indexOf(item.id) === -1;
  }); 

  Logger.log(arr.length)
  Logger.log(arr)
}

这将返回完整列表。

我也试过这个:

function myFunction2(){
  var ss = SpreadsheetApp.getActive();
  var partialListArr = ss.getSheetByName('sheet 2').getRange(1,1,357,1).getValues();
  var fullListArr = ss.getSheetByName('sheet 1').getRange(1,1,942,1).getValues();

  var arr = fullListArr.map(function(e){return e[0];})
    .filter(function(e,i,a){return (a.indexOf(e)==i && partialListArr.indexOf(e) ==-1); })  

  Logger.log(arr.length)
  Logger.log(arr)
} 

它只会返回部分结果。如果fullListArr 有 943,partialListArr 有 288 个唯一值,我应该在 arr 中有 655 个值,但我得到 895,它没有将它作为二维数组返回。

这是一个sheet with a data set,这两个都包括在内。

尝试:如果使用第一个函数,首先我需要展平。

  var ss = SpreadsheetApp.getActive();
  var partialListArr = ss.getSheetByName('sheet 2').getRange(1,1,357,1).getValues();
  var fullListArr = ss.getSheetByName('sheet 1').getRange(1,1,942,1).getValues();

  var flatPartialListArr = [].concat.apply([], partialListArr);
  var flatFullListArr = [].concat.apply([], fullListArr);

  var arr = flatFullListArr.filter(function(item){
    return flatPartialListArr.indexOf(item) === -1;
  }); 

  Logger.log(arr.length)
  Logger.log(arr)

这给了我arr 的正确号码。下一步是再次使它成为一个二维数组,以便我将其插入.setValues。这是具有完整解决方案的功能。

function myFunction() {
  var ss = SpreadsheetApp.getActive();
  var partialListArr = ss.getSheetByName('sheet 2').getRange(1,1,357,1).getValues();
  var fullListArr = ss.getSheetByName('sheet 1').getRange(1,1,942,1).getValues();

  var flatPartialListArr = [].concat.apply([], partialListArr);
  var flatFullListArr = [].concat.apply([], fullListArr);

  var flatArr = flatFullListArr.filter(function(item){
    return flatPartialListArr.indexOf(item) === -1;
  }); 

  //Convert to 2D again for input into .setValues
  var newArr = [];
  while(flatArr.length) newArr.push(flatArr.splice(0,1));

  Logger.log(newArr.length)
  Logger.log(newArr)

  return newArr;
}

谢谢阿克里昂!

【问题讨论】:

  • 你能提供item的结构吗?您的过滤似乎没问题,但也许 id 字段不是您应该过滤的字段?
  • @Akrion 我已经链接了一张表格,以便您查看数据。
  • 工作表给了我原始工作表数据,但没有包含它的实际对象。似乎ss.getSheetByName('sheet 2').getRange(1,1,357,1).getValues() 例如不返回值但对象不?如果没有,那你为什么有item.id
  • @Akrion 日志显示 [[60],[10004],[5678]....]
  • 正是...您有数组数组:) 这意味着您需要先将其展平,然后再进行迭代

标签: javascript arrays google-apps-script array-difference


【解决方案1】:

你好像有这样的东西:

var full = [[1],[2],[3],[4],[5]]
var partial = [[3],[4]]

var result = full.filter(x => !partial.find(p => p[0] === x[0]))
console.log(result)

这将以您想要的方式过滤。简单地说,您的过滤器不起作用,因为您没有考虑返回的结果,即 [[]、[]、[]] 或数组数组。

所以在你的上下文中试试这个:

var arr = fullListArr.filter(item => !partialListArr.find(p ==> p[0] === item[0]);

【讨论】:

  • Arrow 和 find 在 Apps 脚本中不可用
  • 我尝试使用类似的解决方案,但出现语法错误。我假设这是因为谷歌应用程序脚本不采用=>。我可能是错的。
  • @tehhowch 你打败了我。感谢您的确认。
  • @DanCue 好吧,一旦您发现数组的数组是问题所在,您是否能够解决它并不重要?
  • @tehhowch 谢谢我没有在那里测试,而是在控制台中测试,所以这是一个很好的更正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 2013-02-26
  • 1970-01-01
  • 2022-12-07
  • 2016-04-26
  • 1970-01-01
相关资源
最近更新 更多