danielo
danielo

Reputation: 780

Filter array depending on two other arrays efficiently

I have data which could be simply explained with these three arrays (although in a much larger scale):

var arrayOfVariables = ['var1', 'var2', 'var3', 'var4'];
var arrayWithValues = [20, 10, 30, 40];
var arrayToFilter = ['var1', 'var3'];

Ideally I would want to filter the arrayToFilter and see if it contains any variable from my arrayOfVariables. If they do I want to use their indexes to get an array of correct values from the arrayWithValues. This means var1 = 20, var2 = 10, var3 = 30, var4 = 40. Because arrayToFilter contain var1 och var 3 my last array would be:

var output = [20, 30];

Does anyone know if this is possible in a efficient way, preferably without for-loops or similar. Maybe filter/map/reduce?

* UPDATE *

var arrayOfVariables = ['var3', 'var2', 'var1', 'var4'];
var arrayWithValues = [30, 10, 20, 40];
var arrayToFilter = ['var1', 'var3'];

If I would change the order of the arrays to the above I would still like an output of [20, 30]. This means I want the values sorted after the arrayToFilter: So first var1 (20) and then var3 (30).

Upvotes: 1

Views: 85

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386883

You could filter the values by taking the index and look if the value is in the filter array.

var variables = ['var1', 'var2', 'var3', 'var4'],
    values = [20, 10, 30, 40],
    filter = ['var1', 'var3', 'foo'],
    result = values.filter((_, i) => filter.includes(variables[i]));
    
console.log(result);

Version with Array#map. It works only for existing values in variables.

var variables = ['var1', 'var2', 'var3', 'var4'],
    values = [20, 10, 30, 40],
    filter = ['var1', 'var3', 'foo'],
    result = filter.map(f => values[variables.indexOf(f)]);
    
console.log(result);

A 4castle's approach with Map.

var variables = ['var1', 'var2', 'var3', 'var4'],
    values = [20, 10, 30, 40],
    filter = ['var1', 'var3'],
    map = new Map(variables.map((v, i) => [v, values[i]]))
    result = filter.map(f => map.get(f));
    
console.log(result);

Upvotes: 4

brk
brk

Reputation: 50346

You can use array.map and array.indexOf

var arrayOfVariables = ['var1', 'var2', 'var3', 'var4'];
var arrayWithValues = [20, 10, 30, 40];
var arrayToFilter = ['var1', 'var3'];

// map will return a new array
var m = arrayToFilter.map(function(item) {
  // for every element check if that element is present in arrayOfVariables 
  if (arrayOfVariables.indexOf(item) != -1) {
    // if present get the index and get the value from arrayWithValues
    return arrayWithValues[arrayOfVariables.indexOf(item)]
  }
  return x
})

console.log(m)

Upvotes: 2

Nenad Vracar
Nenad Vracar

Reputation: 122155

You can do this with reduce() method, and to check if current element exists in other array you can use indexOf() which will also give you index of that element.

var arrayOfVariables = ['var1', 'var2', 'var3', 'var4'];
var arrayWithValues = [20, 10, 30, 40];
var arrayToFilter = ['var1', 'var3'];

const result = arrayToFilter.reduce(function(r, e) {
  let i = arrayOfVariables.indexOf(e);
  if (i != -1) r.push(arrayWithValues[i])
  return r;
}, [])

console.log(result)

Upvotes: 3

Related Questions