简体   繁体   English

使用 JS 获取姓名缩写

[英]Getting Name initials using JS

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,但是现在我的要求发生了变化,好像名称只包含 1 个或更多然后 2,所以在以下情况下,我如何根据我的要求获得首字母,

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

How can I get above initials from a string in JS?如何从 JS 中的字符串中获取以上首字母?

Also now I only have item.Name string as an input现在我也只有item.Name字符串作为输入

Why no love for regex?为什么不喜欢正则表达式?

Updated to support unicode characters and use ES6 features更新以支持 unicode 字符并使用 ES6 功能

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

You can use this shorthand js你可以使用这个速记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(" "));

Check the getInitials function below:检查下面的getInitials函数:

 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 ):如果有多个名字,则取姓氏的第一个字母(位置names.length - 1的那个):

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

Get First and Last Initial: John Doe Smith => JS获取第一个和最后一个首字母: John Doe Smith => JS

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

Get All Initials: "John Doe Smith" => "JDS"获取所有缩写: "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.获取第一个和最后一个,如果只有第一个,则获取第一个 2。 (OP's question) (OP的问题)

John => JO and "John Doe Smith" => "JS" John => JO"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"国际版: "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注意:如果名称包含 或其他非单词字符,您可以使用/w代替/S或预先对其进行清理

Common Avatar Use-case常见头像用例

Just surprised that none of the answers put Array.reduce() to good use.只是惊讶地发现没有一个答案可以很好地使用Array.reduce()

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 这是用于在 Avatars 中显示姓名的广泛使用案例,您不希望名字首字母重复两次,并且希望将首字母限制为最多 2 个字母

您可以使用以下一行逻辑:

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

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 .此外,如果您的 'fullName' 仅包含一个单词,则array[0]array[array.length - 1]处的单词将是同一个单词,因此我们正在处理第一个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('Prince') // "P"

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

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

'Aniket Kumar Agrawal'.split(' ').map(x => x.charAt(0)).join('').substr(0, 2).toUpperCase()
let initial = username.match(/\b(\w)/g).join('')

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/小提琴:http: //jsfiddle.net/5v3n2f95/1/

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('');
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'));

Similar but slightly neater version of @njmwas answer: @njmwas 的类似但稍微简洁的版本回答:

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.

+ efficient + 高效
+ no loops + 没有循环
+ simplified branching (ternary operator only) + 简化的分支(仅限三元运算符)
+ handles no-space cases (prints 2 chars) + 处理没有空格的情况(打印 2 个字符)
+ no array memory allocation (actually no array processing) - requires trimmed string input + 没有数组内存分配(实际上没有数组处理) - 需要修剪的字符串输入

 function getInitials(name) { const hasTokens = name.indexOf(' ') !== -1 return name.substring(0, hasTokens ? 1 : 2) + (hasTokens ? name.charAt(name.lastIndexOf(' ') + 1) : '') } console.log(getInitials("AB"), 'AB') console.log(getInitials("Abc Def"), 'AD') console.log(getInitials("Abc Xyz"), 'AX') console.log(getInitials("S Xyz"), 'SX') console.log(getInitials("SXyz "), 'SX') console.log(getInitials("T30"), 'T3')

This solution uses Array capabilities, Arrow function and ternary operator to achieve the goal in one line.该解决方案使用 Array 功能、Arrow 函数和三元运算符来实现目标。 If name is single word, just take first two chars, but if more, then take 1st chars of first and last names.如果 name 是单个单词,只取前两个字符,但如果更多,则取名字和姓氏的第一个字符。 (thanks omn for reminding single word name use case) (感谢 omn 提醒单个单词名称用例)

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()

I needed this today to act as method in my React code.我今天需要这个作为我的 React 代码中的方法。 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();
 }

 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: Safari 尚不支持正则表达式中的lookbehinds(请参阅caniuse ),因此如果需要 Safari 支持,可以这样重写:

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("") || ""
  );
}
  const getInitials = name => {
    let initials = '';
    name.split(' ').map( subName => initials = initials + subName[0]);
    return initials;
  };

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.我希望这有帮助。

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

This should work for majority of the cases including middle names and first name only (extension on @njmwas answer).这应该适用于大多数情况,包括中间名和名字(@njmwas 答案的扩展名)。

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();

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.我希望这会有所帮助,干杯。

Use initials , it handles most of the cases and has covered all senarios of a name.使用首字母,它可以处理大多数情况,并且涵盖了名称的所有情况。

to check how it works visit, try adding your name on https://github.com/gr2m/initials要检查它是如何工作的,请尝试在https://github.com/gr2m/initials上添加您的姓名

Thanks谢谢

One more way to do the same.另一种方法来做同样的事情。

 function getInitials(str) { const FirstName = str.split(' ')[0]; const LastName = str.split(' ').reduceRight(a => a); // Extract the first two characters of a string if (FirstName === LastName) { return FirstName.trim() .substring(0, 2) .toUpperCase(); } // Abbreviate FirstName and LastName return initials = [FirstName, LastName] .map(name => name[0]) .join('').toUpperCase(); } console.log(getInitials('FullName')); console.log(getInitials('FirstName MiddleName LastName')); console.log(getInitials('1stName 2ndName 3rdName 4thName 5thName'));

Easy way using ES6 Destructering :使用ES6 解构的简单方法:

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

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"这是通过简单地将名称传递给 getInitials 函数来帮助获取名称首字母的简单实用方法 // 例如 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();
}

Something more functional: D更实用的东西: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
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')); 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'));

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();
}

just updated Andrea's version:刚刚更新了 Andrea 的版本:

var getInitials = function (string) {
   var initials = "";
   var names = string.split(' ');
   for (n = 0; n < names.length; n++) {
        initials += names[n].substring(0, 1).toUpperCase();
    }
    return initials;
};

if string includes LastName, just change names.length to names.length-1 to ignore lastname如果字符串包含姓氏,只需将names.length更改为names.length-1即可忽略姓氏

Using some es6 functionality:使用一些 es6 功能:

 const testNameString = 'Hello World'; const testNameStringWeird = 'Hello darkness My - Óld Friend Nikolaus Koster-Walder '; const getInitials = nameString =>{ const regexChar = /\D\w+/ return nameString .trim() //remove trailing spaces .split(' ') // splits on spaces .filter(word => word.length > 0) // strip out double spaces .filter(word => regexChar.test(word)) // strip out special characters .map(word => word.substring(0, 1).toUpperCase()) // take first letter from each word and put into array } console.log('name:',testNameString,'\n initials:',getInitials(testNameString)); console.log('name:',testNameStringWeird,'\n initials:',getInitials(testNameStringWeird));

I saw a bunch of overcomplicated ways to do this.我看到了一堆过于复杂的方法来做到这一点。 I'm really more into simplifying things as much as possible, and enhance things using composition or currying.我真的更喜欢尽可能简化事物,并使用组合或柯里化来增强事物。

Here are my 2 cents:这是我的 2 美分:


// Helpers

const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
const reverseText = (text = '')=> text.split('').reverse().join('');

const getInitialsDelimitBy = (delimiter = ' ') => (displayName = '') =>
  displayName
    .trim()
    .split(delimiter)
    .reduce((acc, value) => `${acc}${value.charAt(0)}`, '')
    .toUpperCase();

const getInitialsDelimitByComas = pipe(
  getInitialsDelimitBy(','), 
  reverseText
);

const getInitialsDelimitBySpaces = getInitialsDelimitBy(' '); // Not necessary because of the default but clearer 

const comaInitials = getInitialsDelimitByComas('Wayne, Bruce') // BW
const spaceInitials = getInitialsDelimitBySpaces('Bruce Wayne') // BW

For your specific case I would suggest something like this:对于您的具体情况,我会建议这样的事情:

const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);

const nameProcessor = {
  single: (name = '') =>
    name
      .trim()
      .substring(0, 2)
      .toUpperCase(),
  multiple: pipe(
    name => name.trim().split(' '),
    words => `${words[0].charAt(0)}${words[words.length - 1].charAt(0)}`,
    initials => initials.toUpperCase(),
  ),
};

const getInitials = (displayName = '') => 
  displayName.split(' ').length === 1 
    ? nameProcessor.single(displayName) 
    : nameProcessor.multiple(displayName)

getInitials('FullName') // FU
getInitials('FirstName MiddleName LastName') // FL
getInitials('1stName 2ndName 3rdName 4thName 5thName') // 15

I hope that helps =D希望对你有帮助 =D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM