Typescript数组map与filter有什么区别?

5
这是一个TypeScript方法,它想要遍历一个字符串数组,并返回另一个字符串数组,其中匹配正则表达式(格式类似于“[la la la]”)的字符串将变为“la la la”,不匹配的字符串将被删除。因此,如果我的输入数组是:
"[x]", "x", "[y]"

它变成了

"x", "y"

以下是我的代码:

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

我得到了这样的输出结果:

"x", undefined, "y"

由于存在 "if (match)",请问应该如何正确编写此代码的typescript/javascript版本?


3
之后您可以尝试使用.filter(Boolean)来除去未定义的值。 - elclanrs
5个回答

5

只需将它们过滤出去:

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

filter(x=>!!x)是什么意思?我知道filter的作用,但参数让我困惑。=>创建了一个匿名函数,但为什么这个特定的表达式有效我不理解! - pitosalas
1
@pitosalas 这只是检查值是否为真。x 是一个值,!x 如果 x 为空或为假,则为真,!!x 基本上将该值转换为布尔值。!!"" = false !"" = true !!!"" = true !!"not false" = true - Mathijs Segers

1

map函数的作用是将你的函数应用于列表中的每个元素。当正则表达式不匹配时,你的函数不返回任何值。所以,可能JS会让它返回undefined。如果你想删除不匹配正则表达式的元素,你应该立即使用filter函数。

想一想函数的名称,你就能立刻更好地理解(map将函数映射到列表,而filter过滤列表)。


0
另一个选项是使用 reduce() 方法,像这样:
return this.rawRecords[0].reduce((acc, value) => {
    console.log(value);
    var match = regexp.exec(value);
    if (match) {
        acc.push(match[1]);
    }
    return acc;
}, []);

请在JSFIDDLE中检查JavaScript等效代码的结果。

0

我真的相信有时候我们试图过于追求函数化。

这个有什么问题:

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;

这不是一个一行代码的问题,即使我对TypeScript一无所知(你在问题中也提到了JavaScript),它也应该比任何函数式方法更有效率。


我不确定我同意你的看法... 一旦我理解了 Ruby 中 "map" 的语义,我发现那些一两行的代码更加清晰易懂。(顺便说一下,我正在学习 TypeScript 的同时学习 JavaScript(实际上我之前知道一些 js,但从未在 web 应用程序中编写过超过两行的代码)) - pitosalas
我同意很多时候这样做确实更清晰(虽然我不使用TS,但很多lodash/underscore库都是这样)。但在Ruby世界中,你试图做的事情将会在map之后调用compact,这被认为是设计不良代码的标志。 - Jerska

0

我尝试解决了这个问题,并在下面分享了我的结果。希望这能有所帮助。如果我犯了错误或误解了什么,请谅解,因为我对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]);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接