5

I have an array of arrays , and I need to filter by position 0 of the elements.

I need to filter multiple values extracted from another array, so OR operator is not my way because the amount of values I have is not fixed.

var arr = [
    ["202",27,44],
    ["202",194,35],
    ["200",233,344],
    ["190",333,444],
];

var newArr = arr.filter(function(item){
    //fixed amount of values, not working for my purpose
    return item[0] === "190" || item = "200"
});

I need something like

var newArr = arr.filter(function(item){    
    return item[0] === filterValues
    //where filterValues = ["190","200",etc]
});

function in this case should return :

[["200",233,344],["190",333,444]]

This question uses underscorejs but im new to javascript so it was hard to me to apply it to my problem.

And this is for Angularjs.

I hope you can give me a hand.

P.S : Sorry about my english, its not my native language.

regards

Community
  • 1
  • 1
llermaly
  • 2,331
  • 2
  • 16
  • 29
  • `ok=["190", "200"]; data.filter(/./.test, RegExp("^("+ok.join(")|(")+")"));` – dandavis Jan 10 '16 at 22:07
  • 1
    `arr.filter(function(item){return ["190","200"].indexOf(item[0])>=0})` – CupawnTae Jan 10 '16 at 22:08
  • @CupawnTae: i think you want -1 instead of 0. also, it would be better to define the array outside the callback to reduce object creation costs. you can pass it to filter() as _this_ – dandavis Jan 10 '16 at 22:09
  • 1
    @dandavis why? You mean `>-1` instead of `>=0` maybe? – CupawnTae Jan 10 '16 at 22:10
  • like`arr.filter(function(item){return this.indexOf(item[0])!=-1}, ["190","200"])` or now+later: `arr.filter(function(item){return this.includes(item[0])}, ["190","200"])` – dandavis Jan 10 '16 at 22:11
  • 2
    @CupawnTae, why don't you write it as an answer? – Shomz Jan 10 '16 at 22:14
  • @Shomz no time - if no-one has posted an answer when I get back I will :-) – CupawnTae Jan 10 '16 at 22:16
  • Just copy-paste it (so it's on your name), I'll edit it if needed. :) – Shomz Jan 10 '16 at 22:17
  • 1
    @Shomz thanks, done. I actually only sat down to fish a splinter out of my finger, back to work now :-) – CupawnTae Jan 10 '16 at 22:20
  • arr.filter(function(item){return this.includes(item[0])}, ["190","200"]) did the trick and looks friendly to me, I'll be waiting for dandavis answer , my only doubt is about efficiency because I have to filter 2000 elements – llermaly Jan 10 '16 at 22:21
  • @llermaly, I doubt you can get faster than searching the index unless you reorganize your data a bit (say, sort the original array and manually search only up to a queried index, etc.). – Shomz Jan 10 '16 at 22:34
  • @llermaly the problem with `includes()` is that it's very very new and not supported very widely - for details see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes#Browser_compatibility – CupawnTae Jan 10 '16 at 22:44
  • @CupawnTae im using CasperJS (PhantomJS 1.9.2) , I will test now and then comment – llermaly Jan 10 '16 at 22:46

2 Answers2

10

You can use indexOf() on an array to find if the array contains a value. It will be -1 if not present, otherwise it will be the index in the array of the first instance of the value, i.e. >=0

So, for example:

arr.filter(function(item){return ["190","200"].indexOf(item[0])>=0})

As per your comment, the filters keys are embedded inside nested arrays. You can extract these using map(), e.g.

var keys = [["190",222],["200",344]].map(function(inner){return inner[0]});

A function implementing this (thanks to @Shomz for the bulk of the code) would look like:

var arr = [
    ["202",27,44],
    ["202",194,35],
    ["200",233,344],
    ["190",333,444],
];
  
function myFilter(query) {
  return arr.filter(function(item){
    return query.indexOf(item[0]) >= 0;
  })
}

var q = [["190",222],["200",344]];
var keys = q.map(function(inner){
  return inner[0];
});

alert(myFilter(keys));
Community
  • 1
  • 1
CupawnTae
  • 14,192
  • 3
  • 29
  • 60
  • 1
    Added a quick full example so OP can see it in action here. – Shomz Jan 10 '16 at 22:30
  • Thanks! , tested in CasperJS and working. I tried with 'include()' answer and didnt work . I dont know if it was my fault or PhantomJS 1.9.2 is not supporting this method yet – llermaly Jan 10 '16 at 23:10
  • just noticed that my "query" array is array of arrays too .. tried with var q = [["190",222],["200",344]]; return query[0].indexOf(item[0]) >= 0; but just returned ["190",333,44] :( – llermaly Jan 10 '16 at 23:22
  • @llermaly yeah, that won't work - one solution would be to map the inner arrays to their first element, e.g. `var q = [["190",222],["200",344]].map(function(inner){return inner[0]});` – CupawnTae Jan 10 '16 at 23:55
  • 1
    Thanks ! I have so much to learn , but I'm happy theres people like you around there, I hope to be answering soon :) . Have a nice day – llermaly Jan 11 '16 at 02:24
3
const compare_set = ["190", "200", "201"] // here we can set the numbers we want to use to filter the rows, only for educational purposes, i suppose you will extract them from another place.

const result = arr.filter(o => compare_set.includes(o[0]))

Array.includes looks for a value inside the Array, if exists returns true, and filter expects a true. if not is discarded.

Sebastián Espinosa
  • 2,123
  • 13
  • 23