pitosalas
pitosalas

Reputation: 10852

Typescript array map vs filter vs?

Here's a typescript method that wants to walk through an array of strings, and return another array of strings, where, strings that match the regexp (formatted something like "[la la la]" will become just "la la la" and strings that don't match are dropped. So that if my input array is:

"[x]", "x", "[y]"

it becomes

"x", "y"

Here's my code:

questions(): string[] {
    var regexp = /\[(.*)\]/;
    return this.rawRecords[0].map((value) => {
        console.log(value);
        var match = regexp.exec(value);
        if (match) {
            return match[1];
        }
    });
}

I end up with output like this:

"x", undefined, "y"

because of the "if (match)". What's the right typescript/javascript way of writing this code?

Upvotes: 6

Views: 33781

Answers (5)

Jeyanth
Jeyanth

Reputation: 641

I tried out this problem and shared my result below. Hope this helps. Kindly apologize if I failed or misinterpreted,as I'm new to Typescript.

var arr = ["[xy]","x","y"];
var ele =[];
var i;
var op;
var regex = /\[(.*)\]/;
var op1 = arr.filter((element)=>
{
    op =regex.exec(element);
    if(op)
    ele.push(op);
    else{
        ele.push(element);
        console.log(op);
    }
    });
    for(i =0;i<ele.length;i++)
    {
        console.log(ele[i]);
    }

Upvotes: 0

codanza
codanza

Reputation: 53

What map does is to apply your function to each and every element in your list. Your function does not return any value when regex is not matched. So, probably JS makes it return undefined for that cases. If you wanna drop the ones that do not match regexp, you should use filter right away.

Think about names of functions and you will have a better understanding right away(map maps a function to a list and filter filters a list).

Upvotes: 1

marianc
marianc

Reputation: 449

Another option is to use reduce() method like this:

return this.rawRecords[0].reduce((acc, value) => {
    console.log(value);
    var match = regexp.exec(value);
    if (match) {
        acc.push(match[1]);
    }
    return acc;
}, []);

please check in JSFIDDLE the result for the equivalent code in javascript.

Upvotes: 0

Jerska
Jerska

Reputation: 12002

I really believe that sometimes, we try to go way more functional than we should.
What is wrong with this:

var regexp = /\[(.*)\]/;
var records = this.rawRecords[0];
var res = [];

for (var i = 0, len = records.length; i < len; ++i) {
    var match = regexp.exec(records[i]);
    if (match) {
        res.push(match[1]);
    }
});

return res;

It's not a one-liner, and even if I don't know anything about TypeScript (you also asked about JavaScript in your question), it should also be more efficient than any functional approach.

Upvotes: 0

basarat
basarat

Reputation: 276269

Just filter them out:

return this.rawRecords[0].map((value) => {
        console.log(value);
        var match = regexp.exec(value);
        if (match) {
            return match[1];
        }
    });
}).filter(x=>!!x);

Upvotes: 5

Related Questions