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!
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 ] ]
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