1
votes

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).

3
A better format would be if you constructed a Map with the key/value pairs taken from the first two arrays. - 4castle
@4castle, that works only if all values are in the variables array. if not, the it produces undefined for missing items. - Nina Scholz
@NinaScholz The missing items can be checked using has. The point of using Map is that it has much faster lookup times than a call to indexOf or includes. It makes the quadratic solution into a linear one. - 4castle

3 Answers

4
votes

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);
3
votes

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)
2
votes

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)