gender-rus
Version:
guessing the gender based on Russian name, surname and patronymic
513 lines (503 loc) • 10.8 kB
JavaScript
;
const Gender = {
male: "male",
female: "female",
undefined: "undefined"
};
const popularNames = {
male: [
"абрам",
"авдей",
"аверьян",
"авксентий",
"авраам",
"агафон",
"адам",
"азар",
"акакий",
"аким",
"аксён",
"александр",
"алексей",
"альберт",
"альвиан",
"анатолий",
"андрей",
"андрон",
"аникита",
"антип",
"антон",
"антонин",
"анфим",
"аполлон",
"аристарх",
"аркадий",
"арнольд",
"арсений",
"арсентий",
"артем",
"артемий",
"артур",
"артём",
"архипп",
"аскольд",
"афанасий",
"богдан",
"борис",
"борислав",
"бронислав",
"вавила",
"вадим",
"валентин",
"валерий",
"валерьян",
"варлам",
"варсонофий",
"варфоломей",
"василий",
"венедикт",
"вениамин",
"венцеслав",
"веньямин",
"викентий",
"виктор",
"вилен",
"виссарион",
"виталий",
"владилен",
"владимир",
"владислав",
"владлен",
"влас",
"всеволод",
"всеслав",
"вячеслав",
"гавриил",
"галактион",
"геласий",
"геннадий",
"георгий",
"герасим",
"герман",
"германн",
"глеб",
"гордей",
"григорий",
"давид",
"данакт",
"даниил",
"данил",
"данила",
"демид",
"демьян",
"денис",
"димитрий",
"дмитрий",
"добрыня",
"донат",
"дорофей",
"евгений",
"евграф",
"евдоким",
"евсей",
"евстафий",
"егор",
"емельян",
"еремей",
"ермолай",
"ерофей",
"ефим",
"ефрем",
"ждан",
"захар",
"зиновий",
"иакинф",
"иван",
"игнат",
"игнатий",
"игорь",
"иларион",
"илларион",
"илья",
"иннокентий",
"иосиф",
"ираклий",
"ириней",
"исидор",
"иулиан",
"казимир",
"капитон",
"карп",
"касьян",
"ким",
"кир",
"кирилл",
"климент",
"кондрат",
"конон",
"константин",
"корнилий",
"ксенофонт",
"кузьма",
"куприян",
"лавр",
"лаврентий",
"лазарь",
"ларион",
"лев",
"леонард",
"леонид",
"леонтий",
"логгин",
"лука",
"лукий",
"лукьян",
"магистриан",
"макар",
"максим",
"марат",
"марк",
"мартын",
"матвей",
"мелентий",
"мефодий",
"мина",
"мирон",
"мирослав",
"митрофан",
"михаил",
"моисей",
"мстислав",
"назар",
"нестор",
"никанор",
"никита",
"никифор",
"никодим",
"николай",
"никон",
"олег",
"онисим",
"онуфрий",
"осип",
"остап",
"павел",
"паисий",
"панкрат",
"панкратий",
"пантелей",
"пантелеймон",
"парамон",
"парфений",
"пафнутий",
"пахомий",
"петр",
"платон",
"поликарп",
"порфирий",
"потап",
"пров",
"прокопий",
"протасий",
"прохор",
"пётр",
"разумник",
"роберт",
"родион",
"роман",
"ростислав",
"руслан",
"савва",
"савелий",
"самуил",
"святополк",
"святослав",
"севастьян",
"семен",
"семён",
"серафим",
"сергей",
"сидор",
"сила",
"сильвестр",
"созон",
"софрон",
"спартак",
"спиридон",
"станислав",
"степан",
"тарас",
"терентий",
"тимофей",
"тимур",
"тит",
"тихон",
"трифон",
"трофим",
"ульян",
"урбан",
"фаддей",
"федор",
"федосей",
"федот",
"феликс",
"феоктист",
"филат",
"филимон",
"филипп",
"фирс",
"фока",
"фома",
"фотий",
"фрол",
"фёдор",
"харитон",
"харлам",
"хрисанф",
"христофор",
"эдуард",
"эммануил",
"эраст",
"юлиан",
"юлий",
"юрий",
"юстин",
"яков",
"якун",
"ян",
"ярослав"
],
female: [
"авдотья",
"аврора",
"агата",
"агафья",
"аглая",
"агния",
"агриппина",
"ада",
"аксинья",
"акулина",
"алевтина",
"александра",
"алена",
"алина",
"алиса",
"алла",
"альбина",
"алёна",
"амалия",
"анастасия",
"ангелина",
"анжела",
"анжелика",
"анна",
"антонина",
"анфиса",
"арина",
"белла",
"божена",
"валентина",
"валерия",
"ванда",
"варвара",
"василина",
"василиса",
"вера",
"вероника",
"виктория",
"виола",
"виолетта",
"вита",
"виталия",
"владислава",
"власта",
"галина",
"глафира",
"гликерия",
"дана",
"дарья",
"диана",
"дина",
"ева",
"евгения",
"евдокия",
"евлампия",
"евпраксия",
"евфросиния",
"екатерина",
"елена",
"елизавета",
"епистима",
"ермиония",
"ефросиния",
"ефросинья",
"жанна",
"зинаида",
"зиновия",
"злата",
"зоя",
"ивонна",
"изольда",
"илона",
"инга",
"инесса",
"инна",
"иоанна",
"ираида",
"ирина",
"ия",
"капитолина",
"карина",
"каролина",
"кира",
"клавдия",
"клара",
"клеопатра",
"кристина",
"ксения",
"лада",
"лариса",
"лиана",
"лидия",
"лилия",
"лина",
"лия",
"лора",
"любава",
"любовь",
"людмила",
"майя",
"маргарита",
"марианна",
"мариетта",
"марина",
"мария",
"марта",
"марфа",
"марья",
"марьяна",
"матрена",
"матрона",
"матрёна",
"милена",
"милица",
"милослава",
"мирослава",
"муза",
"надежда",
"настасия",
"настасья",
"наталия",
"наталья",
"нелли",
"ника",
"нина",
"нинель",
"нонна",
"оксана",
"октябрина",
"олимпиада",
"ольга",
"пелагея",
"пинна",
"полина",
"прасковья",
"рада",
"раиса",
"рената",
"римма",
"роза",
"роксана",
"руфь",
"сарра",
"светлана",
"серафима",
"снежана",
"софия",
"софья",
"стелла",
"степанида",
"стефания",
"таисия",
"таисья",
"тамара",
"татьяна",
"улита",
"ульяна",
"урсула",
"устиния",
"устинья",
"фаина",
"феврония",
"фекла",
"феодора",
"фёкла",
"хаврония",
"христина",
"целестина",
"эвелина",
"эдита",
"элеонора",
"элла",
"эльвира",
"эмилия",
"эмма",
"юдифь",
"юлиана",
"юлия",
"ядвига",
"яна",
"ярослава"
]
};
const surnameEndings = {
male: ["ов", "ев", "ин", "ын", "ой", "цкий", "ский"],
female: ["ова", "ева", "ина", "ая", "яя"]
};
const patronymicEndings = {
male: ["ич"],
female: ["овна", "евна", "ична"]
};
module.exports = ({
name: Name = "",
surname: Surname = "",
patronymic: Patronymic = ""
}) => {
const name = Name.toLowerCase();
const surname = Surname.toLowerCase();
const patronymic = Patronymic.toLowerCase();
const genders = {
name: Gender.undefined,
surname: Gender.undefined,
patronymic: Gender.undefined
};
for (const g of [Gender.male, Gender.female]) {
if (genders.name === Gender.undefined && popularNames[g].includes(name)) {
genders.name = g;
}
if (
genders.surname === Gender.undefined &&
surnameEndings[g].some(v => v === surname.slice(-v.length))
) {
genders.surname = g;
}
if (
genders.patronymic === Gender.undefined &&
patronymicEndings[g].some(v => v === patronymic.slice(-v.length))
) {
genders.patronymic = g;
}
}
const isProbablyMale =
genders.name === Gender.male ||
genders.surname === Gender.male ||
genders.patronymic === Gender.male;
const isProbablyFemale =
genders.name === Gender.female ||
genders.surname === Gender.female ||
genders.patronymic === Gender.female;
if (isProbablyMale && !isProbablyFemale) return Gender.male;
if (isProbablyFemale && !isProbablyMale) return Gender.female;
return Gender.undefined;
};