Filter array based on an array of index

First I apologize if it’s a duplicate (I searched but did not find this simple example…), but I want to select elements of arr1 based on the index in arr2:

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

I am using underscore.js but the 0 index is not retrieved (seems to be considered as false):

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

Which returns:

# [77, 8]

How could I fix this, and is there a simpler way to filter using an array of indexes? I am expecting the following result:

# [77, 33, 8]

6 thoughts on “Filter array based on an array of index”

  1. You are returning index, so in your case 0 treated as false. So you need to return true instead

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

    or just return _.contains()

    res = _.filter(arr1, function(value, index){
       return _.contains(arr2, index);
    });
    
    Reply
  2. The simplest way is to use _.map on arr2, like this

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

    Here, we iterate the indexes and fetching the corresponding values from arr1 and creating a new array.


    If your environment supports ECMA Script 6’s Arrow functions, then you can simply do

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

    Moreover, you can use the native Array.protoype.map itself, if your target environment supports them, like this

    console.log(arr2.map((item) => arr1[item]));
    // [ 77, 33, 8 ]
    
    Reply
  3. _.contains returns a boolean. You should return that from the filter predicate, rather than the index because 0 is a falsy value.

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

    As an aside, JavaScript arrays have a native filter method so you could use:

    res = arr1.filter(function(value, index)) {
      return _.contains(arr2, index);
    });
    
    Reply
  4. for me the best way to do this is with 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]
    
    Reply
  5. Isn’t it better to iterate through indices array as main loop?

    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);
    
    Reply
  6. 
    let arr1 = [33, 66, 77, 8, 99];
    let arr2 = [2, 0, 3];
    let output = arr1.filter((_, index) => arr2.includes(index));
    console.log("output", output);
    
    Reply

Leave a Comment