Javascript 过滤函数不允许删除换行符

Javascript Filter Function Not Allowing Removal of Newline Characters

我是 Javascript 的新手,不明白为什么以下两种方法的输出会产生不同的结果。

在第一个示例 (method 1) 中,我从一个空字符串开始,然后遍历示例文本的每个单词并检查它是否是字母数字序列(即 word.trim() !== emptyString).

在第二个示例 (method 2) 中,我 尝试 使用 filter 函数来做同样的事情,删除任何单词非字母数字(换行符、空格、制表符等),然后使用 join 命令 "glue" 将所有内容重新组合在一起。

以下是我的做法:

// Sample Text
// Note the newline characters
let text =
    "quoth that of all the kings of earth \n" +
    "of men he was mildest and most beloved \n" +
    "to his kin the kindest keenest for praise";

// Method 1
let filtered = "";
for (let word of text.split(" ")){
    if(word.trim() !== ""){
        filtered += word.trim() + " "; // word padding via concatenation
    }
}
console.log(filtered, '\n'); // ----------- Output One

// Method 2 - using filter function
let output = text.split(" ").filter(function(word){
    return word.trim() !== "" ? word : "";
}).join(" ");  // word padding via join() method
console.log(output, '\n'); // ----------- Output Two

第一种方法的输出是这样的:

quoth that of all the kings of earth of men he was mildest and most beloved to his kin the kindest keenest for praise 

第二种方法的输出是这样的:

quoth that of all the kings of earth 
of men he was mildest and most beloved 
to his kin the kindest keenest for praise

每种方法都使用相同的word.trim() !== ""过滤逻辑,但第二种方法似乎没有正确过滤掉换行符?

作为完整性检查,我尝试了第二种方法来删除第一个单词 quoth,使用相同的逻辑方法:

// Sanity Check
let outputTwo = text.split(" ").filter(function(word){
    return word !== "quoth" ? word : "";
}).join(" ");
console.log(outputTwo);

输出结果如下:

that of all the kings of earth 
of men he was mildest and most beloved 
to his kin the kindest keenest for praise 

第一个单词 quoth 已如预期删除。

我不明白为什么使用第二种方法没有删除换行符。

注意: 我的问题不是 "how to remove newline characters in javascript"。我知道这可能不是解决这个问题的最有效方法。

更新 谢谢 @Robin Zigmond 指出我愚蠢的逻辑。当使用 split() 函数时,字符串 earth \nof men 将导致 [earth, \nof, men] 是完全合理的。

此外,我可以说以下代码使用建议的 map 函数会产生所需的结果:

// Method 3
let outputThree = text.split(" ").map(
    word => word.trim() !== "" ? word.trim() : ""
).join(" ");
console.log(outputThree, '\n');

虽然在逻辑上相似,但请注意使用 word.trim() 方法进行串联。这显然会将 \nof 等字符串更改为 of.

但是,当从上面调整 method 2 以合并 word.trim() 方法时,它仍然会生成包含换行符的文本。这里:

// Method 2.1 - using filter function
let output = text.split(" ").filter(function(word){
    return word.trim() !== "" ? word.trim() : "";
}).join(" ");  // word padding via join() method
console.log(output, '\n'); // ----------- Output Two.1

通过这一行,现在(我想?)每个方法都使用相同的逻辑;

word.trim() !== "" ? word.trim() : "";

但是使用 filter 的方法似乎仍然没有提取换行符。

更新 谢谢@NikosM — 了解 filter() 函数 returns a boolean 可以清除所有内容。 正在检测 换行符,除此之外不执行任何操作。

因为你的字符串是这样的,手动拼接的话:

let text =
"quoth that of all the kings of earth \nof men he was mildest and most beloved \nto his kin the kindest keenest for praise";

注意换行符直接是"next to"后面的单词,中间没有space。因此,当您对强者调用 split(" ") 时,您最终会得到例如。 "\nof" 作为数组中的条目。

这很重要,因为您的两种方法实际上并没有做同样的事情。第一个在每个 "word" 上添加调用 .trim() 的结果,而第二个只是简单地添加 "word" 不变,前提是它不会 trim 到空字符串。 "\nof" 不会执行后者,因此您最终会在输出字符串中看到它,正如您所看到的。而在第一个代码示例中,您添加 "\nof".trim(),即 "of".

请注意,您可以使用 map 方法对数组的每个元素应用操作,例如此处的 .trim - 在过滤器之前或之后。

为什么不用String.replace效率会高很多。最后,您只想用 space...

替换换行符

// Sample Text
// Note the newline characters
let text =
    "quoth that of all the kings of earth \n" +
    "of men he was mildest and most beloved \n" +
    "to his kin the kindest keenest for praise";

// Method 1
let filtered = text.replace(/\n/, ' ');
console.log(filtered, '\n'); // ----------- Output One