【问题标题】:How to use filter() on a multidimensional array using values from another array?如何使用来自另一个数组的值在多维数组上使用 filter()?
【发布时间】:2019-11-25 15:04:22
【问题描述】:

我有一个多维数组:

var arr1 = 
  [
  [["John"],[50],["Solar"],["Egypt"]],
  [["Joe"],[60],["Wind"],["Ghana"]],
  [["Alan"],[70],["Coal"],["Nigeria"]]
  ]

还有另一个过滤器值数组:

var arr2 = ["Solar","Wind"]

我想使用来自 arr2 的值过滤 arr1。所以结果应该是一个数组:

var results = 
  [
  [["John"],[50],["Solar"],["Egypt"]],
  [["Joe"],[60],["Wind"],["Ghana"]]
  ]

如何使用 .filter() 来实现这一点?我已经尝试过了,但没有成功:

var filtered = var filtered = arr1.filter(function(e) {
  return e[2] == arr2
}
);

【问题讨论】:

标签: javascript multidimensional-array google-apps-script filter


【解决方案1】:

基本上,这不是您检查数组中是否存在值的方式。在 Google Apps 脚本的上下文中,您应该使用 indexOf()(请参阅 here 了解支持的数组方法)。

当您比较e[2] == arr2 时,您实际上是在检查["Solar"] == ["Solar","Wind"]。显然,它不一样。所以你需要检查过滤器数组中是否存在e[2][0],也就是“Solar”。使用arr2.indexOf(e[2][0]) 将返回数组中“Solar”所在位置的索引;如果该值不存在,它将返回-1。所以你需要做的就是检查-1

如果您可以假设过滤器值将始终位于第三位,那么您可以使用这个相当简单的实现。

var arr1 = [
  [["John"],[50],["Solar"],["Egypt"]],
  [["Joe"],[60],["Wind"],["Ghana"]],
  [["Alan"],[70],["Coal"],["Nigeria"]]
];
var arr2 = ["Solar","Wind"];
var result = arr1.filter(function(e) {
  return arr2.indexOf(e[2][0]) != -1;
});
Logger.log(result);

否则,您需要检查数组的所有元素。这种方法假定所有值都包装在它们自己的数组中,因此它使用map() 将它们提取到单个数组中。然后,您可以使用some() 检查所有过滤器值。

var arr1 = [
  [["John"],[50],["Solar"],["Egypt"]],
  [["Joe"],[60],["Wind"],["Ghana"]],
  [["Alan"],[70],["Coal"],["Nigeria"]]
];
var arr2 = ["Solar","Wind"];  
var result = arr1.filter(function(e) {
  var joined = e.map(function(element) { return element[0] });
  return arr2.some(function(filterVal) { return joined.indexOf(filterVal) != -1});
});
Logger.log(result);

【讨论】:

    【解决方案2】:

    filter 在第一个数组上。在每个嵌套数组的回调中,flatten 它并检查是否包含来自第二个数组的元素的some

    编辑:更新答案,因为 App Scripts 不支持 ES6。

    const arr1 = [
      [["John"],[50],["Solar"], ["Egypt"]],
      [["Joe"],[60],["Wind"],["Ghana"]],
      [["Alan"],[70],["Coal"],["Nigeria"]]
    ];
    
    const arr2 = ["Solar", "Wind"];
    
    function flatten(arr) {
      return arr.reduce(function (acc, val) {
        return acc.concat(val);
      }, []);
    }
    
    const out = arr1.filter(function (arr) {
      return arr2.some(function (el) {
        return flatten(arr).indexOf(el) > -1;
      });
    });
    
    console.log(out);

    【讨论】:

    • 我正在使用不允许使用 .flat() 的 Google Apps 脚本
    • @AjayUbhi,我稍微修改了我的答案。
    • 供将来参考,应用程序脚本目前是 ES5。所以,没有...=>flatflatMapArray.from 或其他 ES6 特性
    • @TheMaster,我不知道。感谢您的提醒。
    • 我看到你编辑了你的答案。我知道这很痛苦,但正如我之前的评论中所说,=> 箭头也不支持。
    【解决方案3】:

    var arr1 = [
      [
        ["John"],
        [50],
        ["Solar"],
        ["Egypt"]
      ],
      [
        ["Joe"],
        [60],
        ["Wind"],
        ["Ghana"]
      ],
      [
        ["Alan"],
        [70],
        ["Coal"],
        ["Nigeria"]
      ]
    ];
    var arr2 = ["Solar", "Wind"];
    var filtered = arr1.filter(a1 => arr2.some(a2 => a2 === a1[2][0]));
    
    console.log(filtered);

    【讨论】:

      【解决方案4】:

      不知道为什么您的数据是这样构造的,但您可以使用以下方法:

      var arr1 = 
        [
        [["John"],[50],["Solar"],["Egypt"]],
        [["Joe"],[60],["Wind"],["Ghana"]],
        [["Alan"],[70],["Coal"],["Nigeria"]]
        ]
        
       var arr2 = ["Solar", "Wind"]
       
       console.log(arr1.filter(item => item.flatMap(d => d).some(s => arr2.includes(s))))

      【讨论】:

        【解决方案5】:

        这是一个不假定您的第一个数组元素的顺序的解决方案。不过,它确实假设每个子元素(即["Solar"])只包含一个元素。

        var arr1 = 
          [
          [["John"],[50],["Solar"],["Egypt"]],
          [["Joe"],[60],["Wind"],["Ghana"]],
          [["Alan"],[70],["Coal"],["Nigeria"]]
          ]
        
        
        var arr2 = ["Solar","Wind"]
        
        let result = arr1.filter(el1 => {
          return arr2.some(el2 => el1.find(x => x[0] === el2))
        })
        
        console.log(result)

        【讨论】:

          猜你喜欢
          • 2020-07-27
          • 1970-01-01
          • 2013-09-30
          • 1970-01-01
          • 1970-01-01
          • 2013-08-14
          • 1970-01-01
          • 2020-04-15
          • 1970-01-01
          相关资源
          最近更新 更多