@mikezimm/fps-core-v7
Version:
Library of reusable core interfaces, types and constants migrated from fps-library-v2
75 lines • 3.67 kB
JavaScript
/**
* https://github.com/mikezimm/drilldown7/issues/501
* Parses a full name string using a custom delimiter and returns either the first or last part.
*
* - If the delimiter is found, it splits and returns based on order (e.g., "Last, First").
* - If the delimiter is not found, it splits by whitespace and uses fallback logic:
* - If the selected word is 3 characters or less, it attempts to return 2 words
* to avoid edge cases like "Mr.", "Sr.", "I", "II", etc.
*
* @param name - The full name string (e.g., "LastName, FirstName" or "John Smith").
* @param delimiter - The delimiter to split on (e.g., ",", "|", "/").
* @param part - "First" or "Last" to specify which part to return.
* @param onError - 'Empty' | 'Original' = 'Original' return either empty string or the original
* @returns The parsed first or last name as a string.
*
* @example
* parseName("Doe, John", ",", "First") // Returns "John"
* parseName("Doe, John", ",", "Last") // Returns "Doe"
*
* @example
* parseName("John Smith", ",", "First") // Returns "John"
* parseName("John Smith", ",", "Last") // Returns "Smith"
*
* @example
* parseName("Mr. John Smith", ",", "First") // Returns "John"
* parseName("Sr. Alex", ",", "Last") // Returns "Alex"
*
* @example
* parseName("I Smith", ",", "First") // Returns "I Smith" (because "I" is <= 3 characters)
* parseName("J Smith", ",", "Last") // Returns "J Smith"
*
* @example
* parseName('Doe, John'); // "Doe" (default 'Last', default delimiter)
* parseName('John Smith', 'First'); // "John" (uses default delimiter, even though it's not present)
* parseName('John | Smith', 'Last', '|'); // "Smith"
*/
export function parseDisplayName(name, part = 'Last', delimiter = ',', onError = 'Original') {
// Guard clause: ensure required inputs exist
if (!name || !delimiter || !part)
return '';
// Removes all '.' characters and returns the remaining length
const cleanedLength = (word) => word.replace(/\./g, '').length;
// First try: split using the provided delimiter (e.g., ',' in "Doe, John")
const parts = name.split(delimiter).map(p => p.trim());
// If the delimiter split gave us multiple parts, we assume "Last, First" order
if (parts.length >= 2) {
return part.toLowerCase() === 'first' ? parts[1] : parts[0];
}
// Fallback: split the name by whitespace instead (e.g., "Mrs. Jane Smith")
const words = name.trim().split(/\s+/); // handles multiple spaces
if (words.length === 0)
return ''; // Name was empty or all spaces
// Helper: determine if a word is 3 chars or less (ignoring periods if present)
const isShort = (word) => word.includes('.') && cleanedLength(word) <= 3;
if (part.toLowerCase() === 'first') {
// If the first word is short (like "Dr." or "Mrs."), return it + next word
if (isShort(words[0]) && words.length >= 2) {
return `${words[0]} ${words[1]}`;
}
// Otherwise, return just the first word
return words[0];
}
if (part.toLowerCase() === 'last') {
const lastWord = words[words.length - 1];
// If the last word is short (like "Jr."), return previous + last
if (isShort(lastWord) && words.length >= 2) {
return `${words[words.length - 2]} ${lastWord}`;
}
// Otherwise, return just the last word
return lastWord;
}
// If something went wrong or part was invalid, return fallback
return onError === 'Empty' ? '' : name;
}
//# sourceMappingURL=parseDisplayName.js.map