diff --git a/index.js b/index.js index 9b259f5..303d446 100644 --- a/index.js +++ b/index.js @@ -3,23 +3,26 @@ var phoneBook = require('./phone-book'); // Эти записи добавятся, вернется true -phoneBook.add('5554440044', 'Григорий', 'grisha@example.com'); -phoneBook.add('5552220022', 'Борис', 'boris@example.com'); -phoneBook.add('5551110011', 'Алекс'); -phoneBook.add('5553330033', 'Валерий', 'valera@example.com'); +console.info(phoneBook.add('5554440044', '', '')); +console.info(phoneBook.add('5552220022', 'Борис', 'boris@example.com')); +console.info(phoneBook.add('5551110011', 'Алекс')); +console.info(phoneBook.add('5553330033', 'Валерий', 'valera@example.com')); // Эти запись не добавятся -phoneBook.add('3330033', 'Неизвестный', 'unknown@example.com'); -phoneBook.add('5551110011', 'Алексей'); -phoneBook.add('5555550055'); +console.info(phoneBook.add('3330033', 'Неизвестный', 'unknown@example.com')); +console.info(phoneBook.add('5551110011', 'Алексей')); +console.info(phoneBook.add('5555550055')); // Обновление phoneBook.update('5551110011', 'Алексей', 'alex@example.com'); phoneBook.update('5553330033', 'Валерий'); + // В следующих примерах вернутся все записи -console.info(phoneBook.find('*')); +console.info(phoneBook.find('')); +// phoneBook.find('*'); console.info(phoneBook.find('555')); +// phoneBook.find('555'); // Вывод будет следующий // [ // 'Алексей, +7 (555) 111-00-11, alex@example.com', @@ -29,16 +32,16 @@ console.info(phoneBook.find('555')); // ] // Удаление -phoneBook.findAndRemove('@'); // returns 3 +console.info(phoneBook.findAndRemove('')); // returns 3 if (phoneBook.isStar) { // Импортируем из csv var csv = [ - 'Борис;5552220022;boris@example.com', + 'Борис;5552220022', 'Григорий;5554440044;grisha@example.com', 'Алексей;5551110011;alex@example.com', 'Валерий;5553330033;valera@example.com', 'Неизвестный;3330033;unknown@example.com' ].join('\n'); - phoneBook.importFromCsv(csv); // returns 4 + console.info(phoneBook.importFromCsv(csv)); // returns 4 } diff --git a/phone-book.js b/phone-book.js index 69fb468..c9ac363 100644 --- a/phone-book.js +++ b/phone-book.js @@ -9,42 +9,214 @@ exports.isStar = true; /** * Телефонная книга */ -var phoneBook; +var phoneBook = []; /* {phone: string, name: string, (email: string)*/ /** * Добавление записи в телефонную книгу * @param {String} phone * @param {String} name * @param {String} email + * @returns {boolean} */ +var phoneReg = /\d+/; exports.add = function (phone, name, email) { + if (addNote(phone, name, email)) { + phoneBook.sort(compareByName); + return true; + } + + return false; }; +function addNote(phone, name, email) { + if (!isCorrectPhone(phone) || phoneBook.some(isPhoneInBook, phone) || !isCorrectName(name)) { + return false; + } + phoneBook.push(createPhoneBookObject(phone, name, email)); + + return true; +} + +function isCorrectPhone(phone) { + return phone !== undefined && phone.length === 10 && phoneReg.exec(phone)[0].length === 10; +} + +function isCorrectName(name) { + return name !== undefined && name.length !== 0; +} + +function compareByName(note1, note2) { + return note1.name.localeCompare(note2.name); +} + +function createPhoneBookObject(phone, name, email) { + var phoneBookObj = { phone: phone, name: name }; + if (email !== undefined) { + phoneBookObj.email = email; + } + + return phoneBookObj; +} + +/** @this isPhoneInBook + * @param {String} element + * @returns {boolean} + */ +function isPhoneInBook(element) { + return isEquals(element.phone, this); +} + +function isEquals(item1, item2) { + return item1 === item2; +} + /** * Обновление записи в телефонной книге * @param {String} phone * @param {String} name * @param {String} email + * @returns {boolean} */ exports.update = function (phone, name, email) { + if (updateNote(phone, name, email)) { + phoneBook.sort(compareByName); + + return true; + } + return false; }; +function updateNote(phone, name, email) { + if (!isCorrectPhone(phone) || !isCorrectName(name)) { + return false; + } + for (var i = 0; i < phoneBook.length; i++) { + if (phoneBook[i].phone === phone) { + phoneBook[i] = createPhoneBookObject(phone, name, email); + + return true; + } + } + + return false; +} + /** - * Удаление записей по запросу из телефонной книги + * Поиск записей по запросу в телефонной книге * @param {String} query + * @returns {Array} */ -exports.findAndRemove = function (query) { - +exports.find = function (query) { + return findCorrectNotes(query, isNoteInBook).map(stylizeNote); }; /** - * Поиск записей по запросу в телефонной книге + * @param {Object} note + * @returns {String} + */ +function stylizeNote(note) { + var stylizedNote = ''; + stylizedNote += note.name + ', '; + stylizedNote += stylizePhoneNumber(note.phone); + if (note.hasOwnProperty('email')) { + stylizedNote += ', ' + note.email; + } + + return stylizedNote; +} + +/** + * @param {String} phone + * @returns {String} + */ +function stylizePhoneNumber(phone) { + return '+7 (' + phone.slice(0, 3) + ') ' + stylizeLastSevenNumbers(phone); +} + +/** + * @param {String} phone + * @returns {String} + */ +function stylizeLastSevenNumbers(phone) { + var result = ''; + var indexes = [3, 6, 8]; + for (var i = 0; i < indexes.length; i++) { + if (i !== indexes.length - 1) { + result += phone.slice(indexes[i], indexes[i + 1]) + '-'; + } else { + result += phone.slice(indexes[i], phone.length); + } + } + + return result; +} + +/** * @param {String} query + * @param {Function} filterFunc + * @returns {Array} */ -exports.find = function (query) { +function findCorrectNotes(query, filterFunc) { + if (isQueryEmpty(query)) { + return []; + } + if (query === '*') { + query = ''; + } + + return phoneBook.filter(filterFunc, query); +} + +/** + * @param {String} query + * @returns {boolean} + */ +function isQueryEmpty(query) { + return !query || query.length === 0; +} + +/** + * @this isNoteInBook + * @param {Object} item + * @param {String} query + * @returns {boolean} + */ +function isNoteInBook(item, query) { + if (typeof query === 'number') { + query = this; + } + for (var key in item) { + if (item[key].indexOf(query) !== -1) { + return true; + } + } + + return false; +} +/** + * @this isNotNoteInBook + * @param {Object} item + * @returns {boolean} + */ +function isNotNoteInBook(item) { + return !isNoteInBook(item, this); +} + +/** + * Удаление записей по запросу из телефонной книги + * @param {String} query + * @returns {Number} + */ +exports.findAndRemove = function (query) { + var oldPhoneBookLength = phoneBook.length; + if (!isQueryEmpty(query)) { + phoneBook = findCorrectNotes(query, isNotNoteInBook); + } + + return oldPhoneBookLength - phoneBook.length; }; /** @@ -57,6 +229,41 @@ exports.importFromCsv = function (csv) { // Парсим csv // Добавляем в телефонную книгу // Либо обновляем, если запись с таким телефоном уже существует + var notesArray = csv.split('\n'); + var result = notesArray.reduce(countSuccessfulAddsOrUpdates, 0); + phoneBook.sort(compareByName); - return csv.split('\n').length; + return result; }; + +/** + * @param {Number} acc + * @param {String} item + * @returns {Number} + */ +function countSuccessfulAddsOrUpdates(acc, item) { + if (addOrUpdate(item)) { + acc++; + } + + return acc; +} + +/** + * @param {String} note + * @returns {boolean} + */ +function addOrUpdate(note) { + var parsedNote = note.split(';'); + if (parsedNote.length> 3) { + return false; + } + var name = parsedNote[0]; + var phone = parsedNote[1]; + var email = parsedNote[2]; + if (!updateNote(phone, name, email)) { + return addNote(phone, name, email); + } + + return true; +}