MarsMan
MarsMan

Reputation: 13

Filtering values from array

I'm working on a project that allows scheduling of employees. The data is in google sheets, each employee gets workplace designation. There are several possibilities: numbers, Roman numerals, characters, additions,...

The problem is with handling Roman numerals. A whole day is put into array, one item for one employee. My idea is to isolate items containing either 'I' or 'V' (numbers run from I to VII). Next I would like to filter out items that contain some of those letters, but don't fit. Therefore an array with to-be-excluded items is created (these entries are fixed).

Part of the code: (in real, data is fed from sheet. Here is just a sample array)

var monTr = ['u/1', 'I/4', 'G1', 'G23', 'LD', 'E1', 'E2 /3', 'LL', 'VAR', 'III', 'VUV', 'V - 11', 'II', 'PB', 'V', '-', 'IV'];
var toExcl = ['VAR', 'VUV', 'EIT'];

var b = monTr
  .map(function (inp, index) { if (inp.indexOf('I') !== -1 || inp.indexOf('V') !== -1) { return index } })
  .filter(index => index != null);
Logger.log(b);

var c = monTr
  .map(function (inp, index) { if (inp.indexOf('I') !== -1 || inp.indexOf('V') !== -1 && toExcl.forEach(function (item) { inp.indexOf(item) !== -1 })) { return index } })
  .filter(index => index != null);
Logger.log(c); 

First part works as predicted; b contains IDs of everything with I or V. But the second part doesn't work properly; c doesn't contain IDs 11 ('V - 11') and 14 ('V'). What am I doing wrong?

Upvotes: 0

Views: 49

Answers (2)

Ben Stephens
Ben Stephens

Reputation: 3371

I'm not sure this is helpful, but I thought I'd add an example using reduce:

const monTr=['u/1','I/4', 'G1','G23', 'LD', 'E1', 'E2 /3', 'LL', 'VAR', 'III', 'VUV', 'V - 11', 'II', 'PB', 'V', '-', 'IV'];
const toExcl=['VAR', 'VUV', 'EIT'];

const filter_indexes = (filter, array) =>
  array.reduce(
    (acc, value, index) => acc.concat(filter(value) ? index : []),
    []
  );

const criteria_b = (value) => ['I', 'V'].some(letter => value.includes(letter));
const criteria_c = (value) => criteria_b(value) && !toExcl.includes(value);

const b = filter_indexes(criteria_b, monTr);
const c = filter_indexes(criteria_c, monTr);

console.log('b: ', b);
console.log('c: ', c);

Upvotes: 0

Diego
Diego

Reputation: 9571

  1. Clean things up a bit by using includes() instead of indexOf()
  2. You can't return from forEach(), but you can also use includes() on toExcl to accomplish what you require.

const monTr=['u/1','I/4', 'G1','G23', 'LD', 'E1', 'E2 /3', 'LL', 'VAR', 'III', 'VUV', 'V - 11', 'II', 'PB', 'V', '-', 'IV'];
const toExcl=['VAR', 'VUV', 'EIT'];

const b = monTr.map(function(inp, index) {
  if (inp.includes('I') || inp.includes('V')) {
    return index;
  } 
}).filter(index => index != null); 
console.log(b);

const c = monTr.map(function(inp, index) {
  if (inp.includes('I') || inp.includes('V') && !toExcl.includes(inp)) {
    return index
  }
}).filter(index => index != null); 
console.log(c);

Upvotes: 2

Related Questions