Skip to content

Commit 6a65c2a

Browse files
author
cbojar
committed
Make static and fix scope.
1 parent d871ba4 commit 6a65c2a

1 file changed

Lines changed: 146 additions & 148 deletions

File tree

‎parse-names.js‎

Lines changed: 146 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -20,171 +20,169 @@ String.prototype.ucfirst = function() {
2020
return this.substr(0,1).toUpperCase() + this.substr(1,this.length - 1).toLowerCase();
2121
};
2222

23-
function NameParse() {
24-
var me = this;
23+
function NameParse() {}
2524

2625
// split full names into the following parts:
2726
// - prefix / salutation (Mr., Mrs., etc)
2827
// - given name / first name
2928
// - middle initials
3029
// - surname / last name
3130
// - suffix (II, Phd, Jr, etc)
32-
NameParse.prototype.parse = function (fullastName) {
33-
fullastName = fullastName.trim();
34-
// split into words
35-
var unfilteredNameParts = fullastName.split(" ");
36-
var nameParts = [];
37-
var lastName = "";
38-
var firstName = "";
39-
var initials = "";
40-
var j = 0;
41-
var i = 0;
42-
// completely ignore any words in parentheses
43-
for (i=0; i<unfilteredNameParts.length; i++) {
44-
if (unfilteredNameParts[i].indexOf("(") == -1) {
45-
nameParts[j++] = unfilteredNameParts[i];
46-
}
31+
NameParse.parse = function (fullastName) {
32+
fullastName = fullastName.trim();
33+
// split into words
34+
var unfilteredNameParts = fullastName.split(" ");
35+
var nameParts = [];
36+
var lastName = "";
37+
var firstName = "";
38+
var initials = "";
39+
var j = 0;
40+
var i = 0;
41+
// completely ignore any words in parentheses
42+
for (i=0; i<unfilteredNameParts.length; i++) {
43+
if (unfilteredNameParts[i].indexOf("(") == -1) {
44+
nameParts[j++] = unfilteredNameParts[i];
4745
}
48-
var numWords = nameParts.length;
49-
// is the first word a title? (Mr. Mrs, etc)
50-
var salutation = me.is_salutation(nameParts[0]);
51-
var suffix = me.is_suffix(nameParts[nameParts.length - 1]);
52-
// set the range for the middle part of the name (trim prefixes & suffixes)
53-
var start = (salutation) ? 1 : 0;
54-
var end = (suffix) ? numWords - 1 : numWords;
55-
56-
// concat the first name
57-
for (i=start; i<(end - 1); i++) {
58-
word = nameParts[i];
59-
// move on to parsing the last name if we find an indicator of a compound last name (Von, Van, etc)
60-
// we use i != start to allow for rare cases where an indicator is actually the first name (like "Von Fabella")
61-
if (me.is_compound_lastName(word) && i != start) {
62-
break;
63-
}
64-
// is it a middle initial or part of their first name?
65-
// if we start off with an initial, we'll call it the first name
66-
if (me.is_initial(word)) {
67-
// is the initial the first word?
68-
if (i == start) {
69-
// if so, do a look-ahead to see if they go by their middle name
70-
// for ex: "R. Jason Smith" => "Jason Smith" & "R." is stored as an initial
71-
// but "R. J. Smith" => "R. Smith" and "J." is stored as an initial
72-
if (me.is_initial(nameParts[i + 1])) {
73-
firstName += " " + word.toUpperCase();
74-
} else {
75-
initials += " " + word.toUpperCase();
76-
}
77-
// otherwise, just go ahead and save the initial
46+
}
47+
var numWords = nameParts.length;
48+
// is the first word a title? (Mr. Mrs, etc)
49+
var salutation = this.is_salutation(nameParts[0]);
50+
var suffix = this.is_suffix(nameParts[nameParts.length - 1]);
51+
// set the range for the middle part of the name (trim prefixes & suffixes)
52+
var start = (salutation) ? 1 : 0;
53+
var end = (suffix) ? numWords - 1 : numWords;
54+
55+
// concat the first name
56+
for (i=start; i<(end - 1); i++) {
57+
word = nameParts[i];
58+
// move on to parsing the last name if we find an indicator of a compound last name (Von, Van, etc)
59+
// we use i != start to allow for rare cases where an indicator is actually the first name (like "Von Fabella")
60+
if (this.is_compound_lastName(word) && i != start) {
61+
break;
62+
}
63+
// is it a middle initial or part of their first name?
64+
// if we start off with an initial, we'll call it the first name
65+
if (this.is_initial(word)) {
66+
// is the initial the first word?
67+
if (i == start) {
68+
// if so, do a look-ahead to see if they go by their middle name
69+
// for ex: "R. Jason Smith" => "Jason Smith" & "R." is stored as an initial
70+
// but "R. J. Smith" => "R. Smith" and "J." is stored as an initial
71+
if (this.is_initial(nameParts[i + 1])) {
72+
firstName += " " + word.toUpperCase();
7873
} else {
79-
initials += " " + word.toUpperCase();
74+
initials += " " + word.toUpperCase();
8075
}
76+
// otherwise, just go ahead and save the initial
8177
} else {
82-
firstName += " " + me.fix_case(word);
83-
}
84-
}
85-
86-
// check that we have more than 1 word in our string
87-
if ((end - start) > 1) {
88-
// concat the last name
89-
for (j=i; j<end; j++) {
90-
lastName += " " + me.fix_case(nameParts[j]);
78+
initials += " " + word.toUpperCase();
9179
}
9280
} else {
93-
// otherwise, single word strings are assumed to be first names
94-
firstName = me.fix_case(nameParts[i]);
95-
}
81+
firstName += " " + this.fix_case(word);
82+
}
83+
}
9684

97-
// return the various parts in an array
98-
return {
99-
"salutation": salutation || "",
100-
"firstName": firstName.trim(),
101-
"initials": initials.trim(),
102-
"lastName": lastName.trim(),
103-
"suffix": suffix || ""
104-
};
105-
};
106-
107-
// detect and format standard salutations
108-
// I'm only considering english honorifics for now & not words like
109-
this.is_salutation = function (word) {
110-
// ignore periods
111-
word = word.replace(".","").toLowerCase();
112-
// returns normalized values
113-
if (word == "mr" || word == "master" || word == "mister") {
114-
return "Mr.";
115-
} else if (word == "mrs") {
116-
return "Mrs.";
117-
} else if (word == "miss" || word == "ms") {
118-
return "Ms.";
119-
} else if (word == "dr") {
120-
return "Dr.";
121-
} else if (word == "rev") {
122-
return "Rev.";
123-
} else if (word == "fr") {
124-
return "Fr.";
125-
} else {
126-
return false;
85+
// check that we have more than 1 word in our string
86+
if ((end - start) > 1) {
87+
// concat the last name
88+
for (j=i; j<end; j++) {
89+
lastName += " " + this.fix_case(nameParts[j]);
12790
}
128-
};
91+
} else {
92+
// otherwise, single word strings are assumed to be first names
93+
firstName = this.fix_case(nameParts[i]);
94+
}
12995

130-
// detect and format common suffixes
131-
this.is_suffix = function (word) {
132-
// ignore periods
133-
word = word.replace(/\./g,"").toLowerCase();
134-
// these are some common suffixes - what am I missing?
135-
var suffixArray = ['I','II','III','IV','V','Senior','Junior','Jr','Sr','PhD','APR','RPh','PE','MD','MA','DMD','CME'];
136-
for (var i=0; i<suffixArray.length; i++) {
137-
if (suffixArray[i].toLowerCase() == word) {
138-
return suffixArray[i];
139-
}
140-
}
141-
return false;
142-
};
143-
144-
// detect compound last names like "Von Fange"
145-
this.is_compound_lastName = function (word) {
146-
word = word.toLowerCase();
147-
// these are some common prefixes that identify a compound last names - what am I missing?
148-
var words = ['vere','von','van','de','del','della','di','da','pietro','vanden','du','st.','st','la','lo','ter'];
149-
return words.in_array(word);
150-
};
151-
152-
// single letter, possibly followed by a period
153-
this.is_initial = function (word) {
154-
// ignore periods
155-
word = word.replace(".","");
156-
return (word.length == 1);
96+
// return the various parts in an array
97+
return {
98+
"salutation": salutation || "",
99+
"firstName": firstName.trim(),
100+
"initials": initials.trim(),
101+
"lastName": lastName.trim(),
102+
"suffix": suffix || ""
157103
};
104+
};
158105

159-
// detect mixed case words like "McDonald"
160-
// returns false if the string is all one case
161-
// FIXME: No it doesn't. It returns true so long as there is a letter in the string, or if it's empty
162-
// FIXME: Also this does not take in to account the first letter being capitalized
163-
this.is_camel_case = function (word) {
164-
var ucReg = /|[A-Z]+|s/;
165-
var lcReg = /|[a-z]+|s/;
166-
return (word.match(ucReg) != null && word.match(lcReg) != null);
167-
};
168-
169-
// ucfirst words split by dashes or periods
170-
// ucfirst all upper/lower strings, but leave camelcase words alone
171-
this.fix_case = function (word) {
172-
// uppercase words split by dashes, like "Kimura-Fay"
173-
word = me.safe_ucfirst("-",word);
174-
// uppercase words split by periods, like "J.P."
175-
word = me.safe_ucfirst(".",word);
176-
return word;
177-
};
106+
// detect and format standard salutations
107+
// I'm only considering english honorifics for now & not words like
108+
NameParse.is_salutation = function (word) {
109+
// ignore periods
110+
word = word.replace(".","").toLowerCase();
111+
// returns normalized values
112+
if (word == "mr" || word == "master" || word == "mister") {
113+
return "Mr.";
114+
} else if (word == "mrs") {
115+
return "Mrs.";
116+
} else if (word == "miss" || word == "ms") {
117+
return "Ms.";
118+
} else if (word == "dr") {
119+
return "Dr.";
120+
} else if (word == "rev") {
121+
return "Rev.";
122+
} else if (word == "fr") {
123+
return "Fr.";
124+
} else {
125+
return false;
126+
}
127+
};
178128

179-
// helper this.for fix_case
180-
this.safe_ucfirst = function (seperator, word) {
181-
var words = [];
182-
// uppercase words split by the seperator (ex. dashes or periods)
183-
parts = word.split(seperator);
184-
for (var i=0; i<parts.length; i++) {
185-
var thisWord = parts[i];
186-
words[i] = (me.is_camel_case(thisWord)) ? thisWord : thisWord.ucfirst();
129+
// detect and format common suffixes
130+
NameParse.is_suffix = function (word) {
131+
// ignore periods
132+
word = word.replace(/\./g,"").toLowerCase();
133+
// these are some common suffixes - what am I missing?
134+
var suffixArray = ['I','II','III','IV','V','Senior','Junior','Jr','Sr','PhD','APR','RPh','PE','MD','MA','DMD','CME'];
135+
for (var i=0; i<suffixArray.length; i++) {
136+
if (suffixArray[i].toLowerCase() == word) {
137+
return suffixArray[i];
187138
}
188-
return words.join(seperator);
189-
};
190-
}
139+
}
140+
return false;
141+
};
142+
143+
// detect compound last names like "Von Fange"
144+
NameParse.is_compound_lastName = function (word) {
145+
word = word.toLowerCase();
146+
// these are some common prefixes that identify a compound last names - what am I missing?
147+
var words = ['vere','von','van','de','del','della','di','da','pietro','vanden','du','st.','st','la','lo','ter'];
148+
return words.in_array(word);
149+
};
150+
151+
// single letter, possibly followed by a period
152+
NameParse.is_initial = function (word) {
153+
// ignore periods
154+
word = word.replace(".","");
155+
return (word.length == 1);
156+
};
157+
158+
// detect mixed case words like "McDonald"
159+
// returns false if the string is all one case
160+
// FIXME: No it doesn't. It returns true so long as there is a letter in the string, or if it's empty
161+
// FIXME: Also this does not take in to account the first letter being capitalized
162+
NameParse.is_camel_case = function (word) {
163+
var ucReg = /|[A-Z]+|s/;
164+
var lcReg = /|[a-z]+|s/;
165+
return (word.match(ucReg) != null && word.match(lcReg) != null);
166+
};
167+
168+
// ucfirst words split by dashes or periods
169+
// ucfirst all upper/lower strings, but leave camelcase words alone
170+
NameParse.fix_case = function (word) {
171+
// uppercase words split by dashes, like "Kimura-Fay"
172+
word = this.safe_ucfirst("-",word);
173+
// uppercase words split by periods, like "J.P."
174+
word = this.safe_ucfirst(".",word);
175+
return word;
176+
};
177+
178+
// helper this.for fix_case
179+
NameParse.safe_ucfirst = function (seperator, word) {
180+
var words = [];
181+
// uppercase words split by the seperator (ex. dashes or periods)
182+
parts = word.split(seperator);
183+
for (var i=0; i<parts.length; i++) {
184+
var thisWord = parts[i];
185+
words[i] = (this.is_camel_case(thisWord)) ? thisWord : thisWord.ucfirst();
186+
}
187+
return words.join(seperator);
188+
};

0 commit comments

Comments
 (0)