97

I would like to extract initials from a string, like:

Name = FirstName LastName Initials = FL 

I can get the above result using this,

const initials = item .FirstName .charAt(0) .toUpperCase() + item .LastName .charAt(0) .toUpperCase(); 

But now my requirements are changed as if name only consist of 1 word or more then 2, so in following cases how can I get initials as per my requirements,

FullName = FU FirstName MiddleName LastName = FL 1stName 2ndName 3rdName 4thName 5thName = 15 

How can I get above initials from a string in JS?

Also now I only have item.Name string as an input

3
  • Only answer to OP's full question: stackoverflow.com/a/63763497/1602301 Commented Sep 6, 2020 at 11:42
  • If someone is looking for just 1 character for single word with spaces handled - stackoverflow.com/a/66239174/1891625 Commented Feb 18, 2021 at 9:05
  • this does assume that all names are Firstname MiddleName Surname, but there's the edge case of Dutch surnames such as "de Suza", where the de is part of the surname, so really I feel like the case was a bad case from the start Commented Jun 27, 2022 at 15:57

33 Answers 33

96

Why no love for regex?

Updated to support unicode characters and use ES6 features

let name = 'ÇFoo Bar 1Name too ÉLong'; let rgx = new RegExp(/(\p{L}{1})\p{L}+/, 'gu'); let initials = [...name.matchAll(rgx)] || []; initials = ( (initials.shift()?.[1] || '') + (initials.pop()?.[1] || '') ).toUpperCase(); console.log(initials);

Sign up to request clarification or add additional context in comments.

7 Comments

Note that this does not handle a one-word name well. "Prince" has the initials "PUNDEFINED"
@thetallweeks You're right, I edited the code to handle one-word name and empty strings too.
This is for names that only uses the basic 26 alphabets. Does not support names with diacritics.
"Why no love for regex?" Because regex is usually less readable and more prone to being incorrect for corner cases. Just look at the comments on this answer for proof.
Doesn't work for instances where the first name is already an initial. E.g. "K Mehta" should result in "KM"
|
59

You can use this shorthand js

"FirstName LastName".split(" ").map((n)=>n[0]).join("."); 

To get only First name and Last name you can use this shorthand function

(fullname=>fullname.map((n, i)=>(i==0||i==fullname.length-1)&&n[0]).filter(n=>n).join("")) ("FirstName MiddleName OtherName LastName".split(" ")); 

2 Comments

This doesn't quite answer the original question - if you have a MiddleName in there, this returns 'FML'.
maybe replace .join(".") with .reduce((acc, cur) => acc+=cur + '.', '')`, this way You have dot at the end
58

Get First and Last Initial: John Doe Smith => JS

name.match(/(\b\S)?/g).join("").match(/(^\S|\S$)?/g).join("").toUpperCase() 

Get All Initials: "John Doe Smith" => "JDS"

name.match(/(\b\S)?/g).join("").toUpperCase() 

Get First and Last except get First 2 in case there is only first. (OP's question)

John => JO and "John Doe Smith" => "JS"

name.match(/(^\S\S?|\b\S)?/g).join("").match(/(^\S|\S$)?/g).join("").toUpperCase() 

International Version: "Störfried Würgekloß" => "SW"

name.match(/(^\S\S?|\s\S)?/g).map(v=>v.trim()).join("").match(/(^\S|\S$)?/g).join("").toLocaleUpperCase() 

Note: If the name contains , or other non word characters, you might use /w instead of /S or sanitize it beforehand

4 Comments

this solution doesn't yet work with non-english characters such as german umlauts. currently it will produce wrong initials.
@LarsBlumberg can you provide an example name
"Störfried Würgekloß". Current answer yields "SSS" as initials. Should be: "SW"
@LarsBlumberg added to the answer
57

Check the getInitials function below:

var getInitials = function (string) { var names = string.split(' '), initials = names[0].substring(0, 1).toUpperCase(); if (names.length > 1) { initials += names[names.length - 1].substring(0, 1).toUpperCase(); } return initials; }; console.log(getInitials('FirstName LastName')); console.log(getInitials('FirstName MiddleName LastName')); console.log(getInitials('1stName 2ndName 3rdName 4thName 5thName'));

The functions split the input string by spaces:

names = string.split(' '), 

Then get the first name, and get the first letter:

initials = names[0].substring(0, 1).toUpperCase(); 

If there are more then one name, it takes the first letter of the last name (the one in position names.length - 1):

if (names.length > 1) { initials += names[names.length - 1].substring(0, 1).toUpperCase(); } 

Comments

30

Common Avatar Use-case

Just surprised that none of the answers put Array.reduce() to good use.

const getInitials = (fullName) => { const allNames = fullName.trim().split(' '); const initials = allNames.reduce((acc, curr, index) => { if(index === 0 || index === allNames.length - 1){ acc = `${acc}${curr.charAt(0).toUpperCase()}`; } return acc; }, ''); return initials; } 

Run the snippet below to check the initials for different use cases -

const testNames = [ 'Albus Percival Wulfric Brian dumbledore', // AD 'Harry Potter', // HP 'Ron', // R '', // <empty> 'Çigkofte With Érnie', // ÇÉ 'Hermione ', // H (Notice that there is a space after the name) 'Neville LongBottom ' // NL (space after name is trimmed) ] const getInitials = (fullName) => { const allNames = fullName.trim().split(' '); const initials = allNames.reduce((acc, curr, index) => { if(index === 0 || index === allNames.length - 1){ acc = `${acc}${curr.charAt(0).toUpperCase()}`; } return acc; }, ''); return initials; } console.log(testNames.map(getInitials));

Note

This one is for a widely used case for displaying names in Avatars, where you wouldn't want first name initial to be repeated twice and want to restrict the initials to a max of 2 letters

1 Comment

This is the winner for me. Doesn't require me installing any unicode REGEX stuff to make it work on ES5 browsers!
10

You can use below one line logic:

"FirstName MiddleName LastName".split(" ").map((n,i,a)=> i === 0 || i+1 === a.length ? n[0] : null).join(""); 

Comments

9
const initial = username.match(/\b(\w)/g).join('') 

3 Comments

username.match(/\b(\w)/g).join('').toUpperCase() to convert to uppercase
It doesn't work with accents. "John Céna" returns "JN" instead of "JC".
thats uncommon case bro, you can replace \w with character class instead if you want
8

There are some other answers which solve your query but are slightly complicated. Here's a more readable solution which covers most edge cases.

As your full name can have any number of words(middle names) in it, our best bet is to spit it into an array and get the initial characters from the first and last words in that array and return the letters together.

Also if your 'fullName' contains only one word, word at array[0] and array[array.length - 1] would be the same word, so we are handling that if the first if.

function nameToInitials(fullName) { const namesArray = fullName.trim().split(' '); if (namesArray.length === 1) return `${namesArray[0].charAt(0)}`; else return `${namesArray[0].charAt(0)}${namesArray[namesArray.length - 1].charAt(0)}`; } 

Sample outputs :

> nameToInitials('Prince') // "P"

> nameToInitials('FirstName LastName') // "FL"

> nameToInitials('1stName 2ndName 3rdName 4thName 5thName') // "15"

Comments

6
'Aniket Kumar Agrawal'.split(' ').map(x => x.charAt(0)).join('').substr(0, 2).toUpperCase() 

1 Comment

Perhaps provide an explanation to what this is doing?
6

+ efficient
+ no loops
+ simplified branching (ternary operator only)
+ handles no-space cases (prints 2 chars)
+ no array memory allocation (actually no array processing) - requires trimmed string input

function getInitials(name) { const hasTokens = name.includes(' ') return name.substring(0, hasTokens ? 1 : 2) + (hasTokens ? name.charAt(name.lastIndexOf(' ') + 1) : '') } console.log(getInitials("Jan Czochralski"), 'JC') console.log(getInitials("A B"), 'AB') console.log(getInitials('SXyz '), 'SX')

1 Comment

simple, love it, just an adjustment: const hasTokens = name.includes(' ')
5

You can do a function for that:

var name = 'Name'; function getInitials( name,delimeter ) { if( name ) { var array = name.split( delimeter ); switch ( array.length ) { case 1: return array[0].charAt(0).toUpperCase(); break; default: return array[0].charAt(0).toUpperCase() + array[ array.length -1 ].charAt(0).toUpperCase(); } } return false; } 

Fiddle: http://jsfiddle.net/5v3n2f95/1/

Comments

3
const getInitials = name => name .replace(/[^A-Za-z0-9À-ÿ ]/ig, '') // taking care of accented characters as well .replace(/ +/ig, ' ') // replace multiple spaces to one .split(/ /) // break the name into parts .reduce((acc, item) => acc + item[0], '') // assemble an abbreviation from the parts .concat(name.substr(1)) // what if the name consist only one part .concat(name) // what if the name is only one character .substr(0, 2) // get the first two characters an initials .toUpperCase(); // uppercase, but you can format it with CSS as well console.log(getInitials('A')); console.log(getInitials('Abcd')); console.log(getInitials('Abcd Efgh')); console.log(getInitials('Abcd Efgh Ijkl')); console.log(getInitials('Abcd Efgh Ijkl Mnop')); console.log(getInitials('Ábcd Éfgh Ijkl Mnop')); console.log(getInitials('Ábcd - Éfgh Ijkl Mnop')); console.log(getInitials('Ábcd / # . - , Éfgh Ijkl Mnop')); 

Comments

3

Similar but slightly neater version of @njmwas answer:

let name = 'Fred Smith'; let initials = name.split(' ').reduce((acc, subname) => acc + subname[0], '') console.log(initials) // FS 

Or, to include the abbreviation dots:

let name = 'Fred Smith'; let initials = name.split(' ').reduce((acc, subname) => acc + subname[0] + '.', '') console.log(initials) // F.S. 

2 Comments

Great work! I converted it to a function and added trim to make sure it doesn't show 'undefined' incase last name is empty export const getNameInitials = name => { return name.trim().split(' ').reduce((acc, subname) => acc + subname[0], '') } }
Trim is a good addition since it also accounts for any double spaces which are incorrectly added by an end user. However, I wouldn't expect last name to be empty for a full name and still have a space unless the names were stored separately in the database, in which case I think you'd be better off using a function which took the names as arguments rather than concatenating the strings first.
2

Easier with map function:

var name = "First Last"; var initials = Array.prototype.map.call(name.split(" "), function(x){ return x.substring(0,1).toUpperCase();}).join(''); 

1 Comment

This also doesn't quite answer the original question - if you have a MiddleName in there, this returns 'FML'.
2

I needed this today to act as method in my React code. I was getting the user name from the state as props. After that I just passed my method inside my component's props.

getUserInitials() { const fullName = this.props.user.name.split(' '); const initials = fullName.shift().charAt(0) + fullName.pop().charAt(0); return initials.toUpperCase(); } 

Comments

2

There are many complicated answers here...

Simpler solution with Clean code!

I know this question has been around for a while, but I believe this solution is good enough to share with you :)

My goal with this code is to create something that is both intelligent and easy to read.

const names = [ 'Crystals', // -> CR 'undisclosed desires', // -> UD 'Feel so Close - Radio Edit', // -> FE ' ', // -> empty 'Faint ', // -> FA .: Note the space after the name ] function getInitials(fullName) { const [firstName, ...restNames] = fullName.toUpperCase().trim().split(' ') if (!restNames.length) { return firstName.substring(0,2) } const firstNameInitial = firstName[0] const lastNameInitial = restNames.pop()[0] return `${firstNameInitial}${lastNameInitial}` } console.log(names.map(getInitials))

The first line, transforms the string to uppercase, remove unwanted spaces (at the begginning and end) and split the name creating an array. Using the destructuring we recover the firstName and place the rest into a constant called restNames

const [firstName, ...restNames] = fullName.toUpperCase().trim().split(' ') 

after that, we check if there's other names besides the first name, if not, we return the first two letters from it ending the function execution

if (!restNames.length) { return firstName[0].substring(0,2) } 

If we found out that restNames contains other names, we get the first name and the last name initials

const firstNameInitial = firstName[0] const lastNameInitial = restNames.pop()[0] 

Finally, we return the initials!

return `${firstNameInitial}${lastNameInitial}` 

This code aims to be clear and efficient in providing the desired result

1 Comment

I like it and I like that you put case with trailing space :)
1

You can do something like this;

 function initials(name){ //splits words to array var nameArray = name.split(" "); var initials = ''; //if it's a single word, return 1st and 2nd character if(nameArray.length === 1) { return nameArray[0].charAt(0) + "" +nameArray[0].charAt(1); }else{ initials = nameArray[0].charAt(0); } //else it's more than one, concat the initials in a loop //we've gotten the first word, get the initial of the last word //first word for (i = (nameArray.length - 1); i < nameArray.length; i++){ initials += nameArray[i].charAt(0); } //return capitalized initials return initials.toUpperCase(); } 

You can then use the function like so;

 var fullname = 'badmos tobi'; initials(fullname); //returns BT var surname = 'badmos'; initials(surname); //returns BA var more = 'badmos gbenga mike wale'; initials(more); //returns BW; 

I hope this helps.

Comments

1

This solution uses Array capabilities, Arrow function and ternary operator to achieve the goal in one line. If name is single word, just take first two chars, but if more, then take 1st chars of first and last names. (thanks omn for reminding single word name use case)

string.trim().split(' ').reduce((acc, cur, idx, arr) => acc + (arr.length > 1 ? (idx == 0 || idx == arr.length - 1 ? cur.substring(0, 1) : '') : cur.substring(0, 2)), '').toUpperCase() 

1 Comment

You answer would be much better if it explained what the code does and why rather than just providing a snippet. I also don't think it actually has the desired behavior. It looks like it returns the first character of the first and last words, but it does not return the first two characters of the first word if it is the only word.
1

To get the first name and last name initials, try using the function below.

const getInitials = string => { const names = string.split(' '); const initials = names.map(name => name.charAt(0).toUpperCase()) if (initials.length > 1) { return `${initials[0]}${initials[initials.length - 1]}`; } else { return initials[0]; } }; console.log(getInitials("1stName 2ndName 3rdName 4thName 5thName")); // 15 console.log(getInitials("FirstName MiddleName LastName")); // FL 

WHAT HAPPENED: The function splits the incoming string, ignores any name between the first & last names and returns their initials. In the case a single name is entered, a single initial is returned. I hope this helps, cheers.

Comments

1

function getInitials(name) { return ( name .match(/(?<=\s|^)\p{L}\p{Mn}*/gu) ?.filter((el, i, array) => i === 0 || i === array.length - 1) .join("") || "" ); } console.log(getInitials('ÇFoo Bar 1Name too ÉLong')); console.log(getInitials('Q̈lice Hwerty')); // Q is followed by U+0308 (Combining Diaeresis) console.log(getInitials('A Foo')); console.log(getInitials('Bob'));

Safari doesn't yet support lookbehinds in regexes (see caniuse), so if Safari support is needed, it can be rewritten this way:

function getInitials(name) { return ( name .match(/(\s|^)\p{L}\p{Mn}*/gu) ?.filter((el, i, array) => i === 0 || i === array.length - 1) .map(el => el.trimStart()) .join("") || "" ); } 

Comments

1
const name = 'First Second Third' name .split(' ') .slice(0, 2) // <= optional if only two letters are desired .map((name) => name[0]) .join('') // FS 

Comments

0
 const getInitials = name => { let initials = ''; name.split(' ').map( subName => initials = initials + subName[0]); return initials; }; 

Comments

0
var personName = "FirstName MiddleName LastName"; var userArray = personName.split(" "); var initials = []; if(userArray.length == 1){ initials.push(userArray[0][0].toUpperCase() + userArray[0][1]).toUpperCase();} else if(userArray.length > 1){ initials.push(userArray[0][0].toUpperCase() + userArray[userArray.length-1][0].toUpperCase());} console.log(initials); 

Comments

0

This should work for majority of the cases including middle names and first name only (extension on @njmwas answer).

const initialArr = name.split(" ").map((n)=>n[0]); const init = (initialArr.length > 1)? `${initialArr[0]}${initialArr[initialArr.length - 1]}` : initialArr[0]; const initials = init.toUpperCase(); 

Comments

0

Easy way using ES6 Destructering:

const getInitials = string => string .split(' ') .map(([firstLetter]) => firstLetter) .filter((_, index, array) => index === 0 || index === array.length - 1) .join('') .toUpperCase(); 

Comments

0

THIS IS THE SIMPLE UTILITY METHOD THAT HELPS TO GET THE INITIALS OF THE NAME BY SIMPLY PASSING THE NAME TO getInitials function // eg getInitials("harry potter") ==> "HP"

const getInitials = (name) => { var parts = name.split(' ') var initials = '' for (var i = 0; i < parts.length; i++) { if (parts[i].length > 0 && parts[i] !== '') { initials += parts[i][0] } } return initials.toUpperCase(); } 

Comments

0

Something more functional: D

 const getInitials = (string) => { const [firstname, lastname] = string.toUpperCase().split(' '); const initials = firstname.substring(0, 1); return lastname ? initials.concat(lastname.substring(0, 1)) : initials.concat(firstname.substring(1, 2)); }; console.log(getInitials('FirstName LastName')); // FL console.log(getInitials('FirstName MiddleName LastName')); // FM console.log(getInitials('FirstName')); // FI 

Comments

0
var getInitials = function (string) { var names = string.split(' '), initials = names[0].substring(0, 1).toUpperCase()+'.'; if (names.length > 1) { initials += names[names.length - 2].substring(0, 1).toUpperCase()+'.'; } return initials=initials+names[names.length - 1].toUpperCase(); } 

console.log(getInitials('Rama Krishna Narayan'));

var getInitials = function (string) { var names = string.split(' '), initials = names[0].substring(0, 1).toUpperCase()+'.'; if (names.length > 1) { initials += names[names.length - 2].substring(0, 1).toUpperCase()+'.'; } return initials=initials+names[names.length - 1].toUpperCase(); } console.log(getInitials('Rama Krishna Narayan'));

1 Comment

Welcome to SO! Please don't post code-only answers but add a little textual explanation about how and why your approach works and what makes it different from the other answers given. You may also have a look at our "How to write a good answer" entry.
0

A better way.

nameToInitials(name: string): string { const portions = name.split(' ') .map(val => val[0]); return portions.slice(0, 2) .reduce((a, b) => a + b, '').toUpperCase(); } 

Comments

0

I am sorry if I misunderstand something, but most answers are so.... complicated.

My solution is (for international, actually hungarian names):

var regex = /[A-ZÍÉÁŰŐÚÖÜÓ]{1}/g var monogram = 'Üveges Tóth Ödön'.match(regex).join('') 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.