Javascript Функция фильтра, не позволяющая удалять символы новой строки - PullRequest
1 голос
/ 08 марта 2020

Я новичок в Javascript и не понимаю, почему вывод следующих двух подходов дает разные результаты.

В первом примере (method 1) я начинаю с пустая строка с последующим циклом через каждое слово образца текста и проверкой, является ли это последовательность alphanumeri c (т.е. word.trim ()! == emptyString).

Во втором примере (method 2) Я пытаюсь использовать функцию filter, чтобы сделать то же самое, удалив все слова, не являющиеся алфавитными именами c (разрывы строк, пробелы, табуляции и т. Д. c.) а затем с помощью команды join «склеить» все вместе.

Ниже мой подход:

// 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() !== "" logi c для фильтрации, но второй, похоже, неправильно фильтрует символы новой строки?

В качестве проверки работоспособности я попробовал второй подход, чтобы удалить первое слово 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 было удалено, как и ожидалось.

Я не понимаю, почему символы новой строки не удаляются с помощью второго метода.

Примечание: Мой вопрос НЕ "как удалить символы новой строки в javascript ». Я знаю, что это может быть не самый эффективный способ приблизиться к этому.

Обновление Спасибо @Robin Zigmond за указание на мои глупые логики c. Совершенно понятно, что строка earth \nof men может привести к [earth, \nof, men] при использовании функции split().

Также я могу сказать, что следующий код, использующий предложенную функцию map, производит желаемый результат:

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

Хотя аналогично в logi c, обратите внимание на использование подхода 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

Это та же логика c, которая используется в каждом методе сейчас (я думаю?) С помощью этой строки;

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

Но подход, использующий filter по-прежнему не похоже на символ новой строки.

Обновление Спасибо @NikosM - зная, что функция filter() возвращает boolean, все очищается. обнаруживает символ новой строки, просто не выполняет никаких действий после этого.

Ответы [ 2 ]

2 голосов
/ 08 марта 2020

Это потому, что ваша строка следующая, если кто-то выполняет конкатенации вручную:

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";

Обратите внимание, что символы новой строки находятся непосредственно «рядом» со следующим словом, без пробела между ними. Поэтому, когда вы звоните split(" ") на сильном, вы в конечном итоге, например,. "\nof" как записи в массиве.

Это важно, потому что два ваших метода на самом деле не делают одно и то же. Первый добавляет результат вызова .trim() для каждого «слова», тогда как второй просто добавляет «слово» без изменений, при условии, что он не обрезается до пустой строки. "\nof" не делает последнего, так что вы получите это в выходной строке, как видите. Принимая во внимание, что в первом примере кода вы добавляете "\nof".trim(), то есть "of".

Обратите внимание, что вы можете использовать метод map для применения операции, такой как .trim здесь, к каждому элементу массива - до или после фильтра.

0 голосов
/ 08 марта 2020

Почему бы не использовать String.replace, это будет намного эффективнее. И, наконец, вы хотите просто заменить символ новой строки пробелом ...

// 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...