Ankuli
Ankuli

Reputation: 131

filter a array from values stored in array

I have an array

sourceArray = [{'type':'A'}, {'type':'B'}, {'type':'C'}, {'type':'D'}];
arrayB  = ['B', 'C'];

I want to filter array sourceArray from values which arrayB contains. We can do this by iterating arrayB, but just want some good way to do this.

filteredArray = [];
for(x in arrayB)
{
filteredArray.concat( sourceArray.filter(function(e1){ return e1.type == arrayB[x])} );
}

can be have any way to do this more gracefully.

Upvotes: 2

Views: 74

Answers (3)

georg
georg

Reputation: 215039

Just .filter it:

sourceArray = [{'type':'A'}, {'type':'B'}, {'type':'C'}, {'type':'D'}];
arrayB  = ['B', 'C'];

result = sourceArray.filter(function(item) {
  return arrayB.indexOf(item.type) >= 0;
});

document.write("<pre>" + JSON.stringify(result,0,3));

[].filter(func) iterates an array and collects elements for which func returns true. In our function, we check whether arrayB contains item.type and return true if it does (see indexOf).

ES6 solution, for those who already use it:

sourceArray = [{'type':'A'}, {'type':'B'}, {'type':'C'}, {'type':'D'}];
arrayB  = ['B', 'C'];

setB = new Set(arrayB)
result = sourceArray.filter(item => setB.has(item.type))

Upvotes: 5

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382454

There's the solution of filtering and using indexOf, but it contains a hidden iteration which is costly if your arrayB array contains more than just a few elements.

In the general case, the efficient solution is to build a hash map of the elements so that the filtering operation is faster. This can be done like this:

var filteredArray = sourceArray.filter(
    function(v){ return this[v.type] }.bind(arrayB.reduce(
        function(s,v){ s[v]=1; return s }, Object.create(null)
    ))
)

In this code arrayB.reduce(function(s,v){ s[v]=1; return s }, {})) is an object whose keys are the valid types : {B: 1, C: 1}. JavaScript engines are very fast at repetitively retrieving the properties of such an object.

Upvotes: 3

ozil
ozil

Reputation: 7117

var sourceArray = [{
    'type': 'A'
}, {
    'type': 'B'
}, {
    'type': 'C'
}, {
    'type': 'D'
}];
var arrayB = ['B', 'C'];

var desiredArr = sourceArray.filter(function (val) {
    for (var i = 0; i <= arrayB.length; ++i) {
        if (val.type == arrayB[i]){
            return val;
        }
    }
});
alert(JSON.stringify(desiredArr));

Upvotes: 0

Related Questions