Я хотел получить первые буквы имени и фамилии человека, используя современный синтаксис JavaScript. В настоящее время я могу правильно получить первую букву имени и первую букву фамилии.
Моя проблема в том, что если существует более одного имени, я не могу правильно его получить.
Код
const names = ["Joshua Jones of USA", "William Sanders", "Grey Charles", "Carlos James Thomas of Russia", "Peter John Parker", "Juan Carlos Tenaz Lopez III of Spain"];
function getUserInitials(name) {
return name.split(' ').map(w => w.charAt(0).toUpperCase()).splice(0, 2);
}
for (const name of names)
console.info(getUserInitials(name));Ожидаемый результат
JJ, WS, GC, CT, PP, JL



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В своем решении я полностью разбиваю имя по союзам и оставляю только начало. Впоследствии каждое слово, состоящее из нескольких заглавных букв, я также разделяю их. Из этих имен я объединяю первую и последнюю заглавные буквы и возвращаю результат.
function getUserInitials(name) {
// Clean up the name: remove titles, conjunctions, and punctuation
// Carlos James Thomas of Russia ---> Carlos James Thomas
name = name.replace(/(?:\b(?:of|the|and|in|on|at|for|with)\b|[,\.]).*$/gi, '');
// Remove all-uppercase words (e.g., III)
// Juan Carlos Tenaz Lopez III, Mexico ---> Juan Carlos Tenaz Lopez
name = name.replace(/\b[A-Z]+\b.*$/g, '');
// Remove whitespaces
name = name.trim();
// Get names
const words = name.split(' ');
// Get first char from First and Last name
let result = '';
result += words[0].charAt(0).toUpperCase();
if (words.length > 1) result += words[words.length - 1].charAt(0).toUpperCase();
return result;
}
// Test cases
const names = [
"Joshua Jones of USA",
"William Sanders",
"Grey Charles",
"Carlos James Thomas of Russia",
"Peter John Parker",
"Juan Carlos Tenaz Lopez III of Spain",
];
for (const name of names) {
console.info(getUserInitials(name));
}Вместо того, чтобы отфильтровывать слова, написанные полностью с заглавной буквы, давайте отфильтруем только римские цифры.
function getUserInitials(name) {
// Clean up the name: remove titles, conjunctions, and punctuation
// Juan Carlos Tenaz Lopez III of Spain ---> Juan Carlos Tenaz Lopez III
name = name.replace(/(?:\b(?:of|the|and|in|on|at|for|with)\b).*$/gi, '');
// Remove Jr. / Sr.
name = name.replace(/\b(?:Jr|Sr)\.?\b/g, '').replace(/\s*\./g, '');
// Remove Roman numerals
// Juan Carlos Tenaz Lopez III ---> Juan Carlos Tenaz Lopez
// Juan Carlos Tenaz Lopez III Another Name ---> Juan Carlos Tenaz Lopez Another Name
name = name.replace(/\b(?:M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3}))\b/g, '');
// Just tip: After removing the Roman numerals, double spaces were left in place, so from there, we can trim the string if desired
// Juan Carlos Tenaz Lopez Another Name ---> Juan Carlos Tenaz Lopez
name = name.replace(/\s{2}.*$/g, '');
// Remove whitespaces
name = name.trim();
// Get names
const words = name.split(' ');
// Get first char from First and Last name
let result = '';
result += words[0].charAt(0).toUpperCase();
if (words.length > 1) result += words[words.length - 1].charAt(0).toUpperCase();
return result;
}
// Test cases
const names = [
"Joshua Jones of USA",
"William Sanders",
"Grey Charles",
"Carlos James Thomas of Russia",
"Peter John Parker",
"PETER JOHN PARKER",
"Jr. Peter Parker",
"Jr Peter Parker",
"Sr. Peter Parer",
"Sr Peter Parker",
"Juan Carlos Tenaz LOPEZ I",
"Juan Carlos Tenaz LOPEZ MMM EXAMPLE",
"Juan Carlos Tenaz LOPEZ I of Spain",
"Juan Carlos Tenaz LOPEZ II of Spain",
"Juan Carlos Tenaz LOPEZ III of Spain",
"Juan Carlos Tenaz LOPEZ IV of Spain",
"Juan Carlos Tenaz LOPEZ V of Spain",
"Juan Carlos Tenaz LOPEZ VI of Spain",
"Juan Carlos Tenaz LOPEZ IX of Spain",
"Juan Carlos Tenaz LOPEZ X of Spain",
"Juan Carlos Tenaz LOPEZ XVI of Spain",
"Juan Carlos Tenaz LOPEZ XXX of Spain",
"Juan Carlos Tenaz LOPEZ XL of Spain",
"Juan Carlos Tenaz LOPEZ CLX of Spain",
"Juan Carlos Tenaz LOPEZ CD of Spain",
"Juan Carlos Tenaz LOPEZ CM of Spain",
"Juan Carlos Tenaz LOPEZ MMMCDXVIII of Spain",
];
for (const name of names) {
console.info(getUserInitials(name));
}Я не проверял, содержит ли массив только 1 элемент, поэтому первый и последний элементы совпали.
Кроме того, это потребует обязательного использования данных в именах, состоящих только с заглавной буквы, например «ПИТЕР СМИТ».
Это тоже правда. Можно придумать другую логику для римских цифр, хотя из вопроса мне показалось очевидным, что нам следует учитывать только формат заглавной первой буквы.
@connexo. Пожалуйста, учтите это. Это все еще должно работать. имена с большой буквы, например «ПИТЕР СМИТ».
@Джозеф изменился.
Следует отметить, что это все равно позволит решить лишь очень небольшое подмножество возможных имен в реальном мире.
@rozsazoltan. Еще одна вещь, которую я забыл: можете ли вы включить младшего или старшего? Пример: Питер Паркер-младший. Выход будет «PP»
@Джозеф, все ли суффиксы в твоем формате заканчиваются точкой (.)? Итак, стоит ли отфильтровывать все слова, оканчивающиеся на точку в имени (например, J., B., а также Jr., Sr.)? Или вы хотите конкретно перечислить эти сокращения, которые вы хотите отфильтровать?
@rozsazoltan. Просто отфильтруйте младшего/младшего. или старший/старший. Иногда пользователи пропускают точку. Так что да, просто перечислите сокращения
@Джозеф, извини за поздний ответ, это была семейная вечеринка. Я добавил его, как вы просили. Мне пришлось удалить точку отдельно из-за особенности регулярного выражения, хотя я считаю, что нет имени, в котором было бы нормально иметь точку.
Это не удастся, если какое-либо из имен является одним из того, что удаляет ваше первое регулярное выражение. например
"William In" // results in "WW".