【问题标题】:Filter array based on an array of index根据索引数组过滤数组
【发布时间】:2015-10-19 10:11:32
【问题描述】:

首先我很抱歉如果它是重复的(我搜索但没有找到这个简单的例子......),但我想根据arr2 中的索引选择arr1 的元素:

arr1 = [33,66,77,8,99]
arr2 = [2,0,3] 

我正在使用underscore.js但是0索引没有被检索到(似乎被认为是false):

res = _.filter(arr1, function(value, index){
    if(_.contains(arr2, index)){
        return index;
    }
});

返回:

# [77, 8]

我该如何解决这个问题,是否有更简单的方法来使用索引数组进行过滤?我期待以下结果:

# [77, 33, 8]

【问题讨论】:

  • 将 if 语句更改为 if(_.contains(arr2, index) >= 0)
  • @82Tuskers 我认为您将_.containsindexOf 混淆了。
  • 绝对正确! @joews 感谢您指出这一点...

标签: javascript arrays underscore.js


【解决方案1】:

最简单的方法是在arr2上使用_.map,像这样

console.log(_.map(arr2, function (item) {
  return arr1[item];
}));
// [ 77, 33, 8 ]

在这里,我们迭代索引并从arr1 中获取相应的值并创建一个新数组。


相当于上面的,但可能更高级一点,是使用_.propertyOf代替匿名函数:

console.log(_.map(arr2, _.propertyOf(arr1)));
// [ 77, 33, 8 ]

如果您的环境支持 ECMA Script 6 的箭头函数,那么您也可以这样做

console.log(_.map(arr2, (item) => arr1[item]));
// [ 77, 33, 8 ]

此外,如果您的目标环境支持它们,您可以使用本机 Array.protoype.map 本身,就像这样

console.log(arr2.map((item) => arr1[item]));
// [ 77, 33, 8 ]

【讨论】:

    【解决方案2】:

    对我来说,最好的方法是使用 filter

    let z=[10,11,12,13,14,15,16,17,18,19]
    
    let x=[0,3,7]
    
    z.filter((el,i)=>x.some(j => i === j))
    //result
    [10, 13, 17]
    

    【讨论】:

    • 虽然正确,但此解决方案的运行时间与z 的长度和x 的长度成比例。所以如果两者都很长,这将需要很长时间。
    【解决方案3】:

    您正在返回index,因此在您的情况下0 被视为false。所以你需要返回true

    res = _.filter(arr1, function(value, index){
        if(_.contains(arr2, index)){
            return true;
        }
    });
    

    或者直接返回_.contains()

    res = _.filter(arr1, function(value, index){
       return _.contains(arr2, index);
    });
    

    【讨论】:

      【解决方案4】:

      _.contains 返回一个布尔值。您应该从filter 谓词而不是索引中返回它,因为0falsy value

      res = _.filter(arr1, function(value, index)) {
        return _.contains(arr2, index);
      });
      

      顺便说一句,JavaScript 数组有一个原生的 filter 方法,所以你可以使用:

      res = arr1.filter(function(value, index)) {
        return _.contains(arr2, index);
      });
      

      【讨论】:

        【解决方案5】:

        可以对想要子集化的数组使用filter 方法。 filter 遍历数组并返回一个由通过测试的项目组成的新数组。测试是一个回调函数,在下面的示例中是一个匿名箭头函数,它接受必需的currentValue 和可选的index 参数。在下面的示例中,我使用 _ 作为第一个参数,因为它没有被使用,这样 linter 不会将其突出显示为未使用:)。
        在回调函数中,数组的includes 方法用于我们用作索引源的数组,以检查arr1 的当前索引是否是所需索引的一部分。

        let arr1 = [33, 66, 77, 8, 99];
        let arr2 = [2, 0, 3];
        let output = arr1.filter((_, index) => arr2.includes(index));
        console.log("output", output);

        【讨论】:

        • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
        • @Cannicide,请运行上面的代码sn-p
        • 我的评论已自动转换为评论。更准确地说,我的意思是这个答案没有提供对问题的完整答案。是的,您的代码有效,但仅代码的答案通常被认为质量低下且不完整。解释你的代码是做什么的,它是如何工作的,OP 在他们的尝试中犯了什么错误(如果相关)等等。否则,其他努力寻找这个问题的答案的人将无法提高他们对他们的问题及其问题的理解解决方案。
        • @Cannicide,很好,我很抱歉没有遵守 SO 标准。我希望我的修改能让答案更有帮助。
        【解决方案6】:

        将索引数组作为主循环进行迭代不是更好吗?

        var arr1 = [33,66,77,8,99]
        var arr2 = [2,0,3] 
        var result = [];
        for(var i=0; i<arr2.length; i++) {
           var index = arr2[i];
           result.push(arr1[index]);
        }
        
        console.log(result);
        

        【讨论】:

        • 我受不了循环 :) 行太多,玩索引不是一个好主意!
        猜你喜欢
        • 2014-03-04
        • 2013-11-10
        • 2022-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多