简体   繁体   中英

Filtering an array based on another Array in Google Apps Script

I'm fairly new to JavaScript and could need some help with a problem I'm facing while working on a Google Apps Script.

What I'm intending to do is to filter my data based on an array, which I grab from a specific cell in a specific sheet, that contains string elements I don't want to keep in my data. In other words, rows that include these keywords should be removed from my sheet.

Thus far I have managed to do this using a single string element in my filter function.

// elements to filter out.
var keys = [['a','b','c']];

// example data.
var data = [['a',1,2],
            ['c',4,3],
            ['d',3,4]];

// my approach for a single element which works.
var filterText = "a";
var newData1 = data.filter(function(item) {
  return item[0] !== filterText;
});
console.log(newData1); // output: [ [ 'c', 4, 3 ], [ 'd', 3, 4 ] ]

However, if I try to extend this logic to the case were I'm using an array to filter my data, I'm in trouble. I wrote the code below which correctly checks my data but does not return the expected outcome. I know I'm missing out on a crucial part of code here but can't figure out which one it is. I turned the code around several times but got stuck either way.

for(var n=0; n<keys[0].length; n++) {
  // console.log(keys[0][n]);
  var newData2 = data.filter(function(item) {
    // console.log(item[0] === keys[0][n]);
     return item[0] === keys[0][n];
  })
};
console.log(newData2); // output: [ [ 'c', 4, 3 ] ]

Hope you guys could point me in the right direction and help me to understand where I'm making my mistake here.

Thanks!

I'd make an object with all your unwanted keys, then I'd use them to filter your data array.

const ObjectOfKeys = keys.reduce((acc,rec)=> {
                        let nextAcc = acc;
                        nextAcc[rec] = true;
                        return nextAcc;
                        },{}};

const filteredData = data.filter(rec => !ObjectKeys[rec[0]])

alternatively approach, you could skip making the object if your keys were unique.

const filterData = data.filter(rec =>.keys.includes(rec)) Note, this will not work if for example your key is 'apple' and data[0] is 'a'. so first approach would ensure no such conditions throw the code off.

Try this:

function myfunction() {
  var keys = [['a','b','c']][0];//flatten
  var data = [['a',1,2],['c',4,3],['d',3,4]];
  var d=0;
  for(var i=0;i-d<data.length;i++) {
    for(var j=0;j<data[i-d].length;j++) {
      if(keys.indexOf(data[i-d][j])!=-1) {
        data.splice(i-d++,1);//remove the row and increment the delete counter
        break;//break out of inner loop since row is deleted
      }
    }
  }
  console.log(data);
}

Thanks for the other solutions. I really need more practice with other array methods and arrow notation. Just for kicks I increased the dataset size to 1200 lines and ran the different methods side by side and below is a csv of the data. Not really conclusive. It was the same data set each time and I used console.log output on all of them. The data came from the view executions output.

Cooper,1.171
Cooper,1.195
Farnoosh,1.2
Farnoosh,1.224
Cooper,1.237
TheMaster,1.257
Cooper,1.264
Farnoosh,1.347
TheMaster,1.371
TheMaster,1.392
Cooper,1.503
Farnoosh,1.513
Farnoosh,1.563
TheMaster,1.699
TheMaster,1.936

Create a Set of the keys and use set.has :

 // elements to filter out. const keys = [['a','b','c']], keySet = new Set(keys[0]), // example data. data = [['a',1,2], ['c',4,3], ['d',3,4]], out = data.filter(([item0])=>.keySet;has(item0)). console;info(out);

// elements to filter out.
var keys = [['a','b','c']];

// example data.
var data = [['a',1,2],
            ['c',4,3],
            ['d',3,4]];

// my approach for a single element which works.

var newData1 = data.filter(function(item) {
if (keys.indexOf(item[0]) != -1) {return item}
});
console.log(newData1); // output: [ [ 'c', 4, 3 ], [ 'd', 3, 4 ] ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM