diff --git a/Base/Collection.js b/Base/Collection.js new file mode 100644 index 0000000..44943e3 --- /dev/null +++ b/Base/Collection.js @@ -0,0 +1,71 @@ +/** +* Возвращает объект Collection +* +* @param {Array} items Элементы списка +* +* @example Collection([]); +*/ +var Collection = function (items) { + "use strict"; + + var i; + this.items = [] + for (i = 0; i < items.length; i++) { + this.items[i] = items[i].clone(); + } +}; + +/** + * Добавление элемента в коллекцию + * + * @return {Collection} + */ +Collection.prototype.add = function (model) { + "use strict"; + + var result = new this.constructor(this.items); + result.items.push(model); + return result; +}; + +/** + * @param {Function} selector + * + * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter + * + * @example + * new Collection([]).filter(function (item) { + * return item.get('attendee').indexOf("me") !== -1; + * }); + * @return {Collection} + */ +Collection.prototype.filter = function (selector) { + "use strict"; + + return new this.constructor(this.items.filter(selector)); +}; + +/** + * @param {String} fieldName + * + * @see http://javascript.ru/Array/sort + * + * @example + * new Collection([]).sortBy("raiting"); + * @return {Collection} + */ +Collection.prototype.sortBy = function (fieldName) { + "use strict"; + + var result = new this.constructor(this.items); + result.items.sort(function (first, second) { + if (first.get(fieldName) < second.get(fieldName)) { + return -1; + } + if (first.get(fieldName) > second.get(fieldName)) { + return 1; + } + return 0; + }); + return result; +}; \ No newline at end of file diff --git a/Base/Model.js b/Base/Model.js new file mode 100644 index 0000000..20c780a --- /dev/null +++ b/Base/Model.js @@ -0,0 +1,41 @@ +var Model = function (data) { + "use strict"; +}; + +/** + * @param {Object} attributes + * + * @example + * item.set({title: "March 20", content: "In his eyes she eclipses..."}); + */ +Model.prototype.set = function (attributes) { + "use strict"; + var keyName; + for (keyName in attributes) { + this[keyName] = attributes[keyName]; + } +}; + +/** + * @param {String} attribute + */ +Model.prototype.get = function (attribute) { + "use strict"; + return this[attribute]; +}; + +/** + * @param {Object} attributes + */ +Model.prototype.validate = function (attributes) { + "use strict"; + throw new Error('this is Abstract method'); +}; + +Model.prototype.clone = function () { + var attr, temp = new this.constructor(); + for (attr in this) { + temp[attr] = clone(this.get(attr)); + } + return temp; +} \ No newline at end of file diff --git a/Clone.js b/Clone.js new file mode 100644 index 0000000..02cb9f4 --- /dev/null +++ b/Clone.js @@ -0,0 +1,29 @@ +function clone(obj) { + if (null == obj || "object" != typeof obj) { + return obj; + } + + if (obj instanceof Date) { + var copy = new Date(); + copy.setTime(obj.getTime()); + return copy; + } + + if (obj instanceof Array) { + var i, copy = []; + for (i = 0; i < obj.length; ++i) { + copy[i] = clone(obj[i]); + } + return copy; + } + + if (obj instanceof Object) { + var copy = {}; + for (var attr in obj) { + if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]); + } + return copy; + } + + throw new Error("Unable to copy obj! Its type isn't supported."); +} \ No newline at end of file diff --git a/Event/Event.js b/Event/Event.js new file mode 100644 index 0000000..b6bfd6e --- /dev/null +++ b/Event/Event.js @@ -0,0 +1,78 @@ +/** +* Возвращает объект Event +* +* @param {String} [name = "Событие"] Имя события +* @param {String} [address = ""] Адресс события +* @param {Object} time Дата события +* @param {Array} member Участники +* @param {Number} [raiting=3] Важность события (по шкале от 0 до 5) +* +* @example +* Event( +* "Совещание", "Екатеринбург, ул. Тургенева, д. 4, ауд. 150", +* EventTime(new Date(2011, 10, 10, 14, 48, 00), 60), ["я"], 5) +* +* @see EventTime +*/ + +var Event = function (name, address, time, member, raiting) { + "use strict"; + + Model.call(this); + var myTime = time || new EventTime(new Date(), 60); + + this.set({ + name: name || "Событие", + address: address || "", + timeStart: myTime.start, + timeLength: myTime.length, + member: member || [], + raiting: +raiting || 3 + }); +} + +inherits(Event, Model); +Event.prototype.constructor = Event; + + +/** +* Возвращает объект EventTime +* +* @private +* @param {Number|Date} start Начало события +* @param {Number} [length=0] Длительность события в минутрах +* +* @example +* EventTime(new Date(2011, 10, 10, 14, 48, 00), 60) +* +* @return {Object} +*/ +function EventTime(start, length) { + "use strict"; + + return { + "start": +start, + "length": +length || 0 + }; +} + +/** + * Валидация собития + * + * @return {Array} Список ошибок + */ +Event.prototype.validate = function () { + "use strict"; + + var errors = []; + if (this.get("timeLength") < 0) { + errors.push("Продолжительность события меньше допустимой величины"); + } + if (this.get("raiting") < 0) { + errors.puch("Рэйтинг собития меньше допустимой величины"); + } + else if (this.get("raiting") > 5) { + errors.push("Рэйтинг события больше допустимой величины"); + } + return errors; +}; \ No newline at end of file diff --git a/Event/Events.js b/Event/Events.js new file mode 100644 index 0000000..b8f51ad --- /dev/null +++ b/Event/Events.js @@ -0,0 +1,134 @@ +/** + * @return {Object} Список событий + */ +var Events = function (items) { + "use strict"; + + Collection.call(this, items); +}; + +inherits(Events, Collection); +Events.prototype.constructor = Events; + +/** + * Прошедшие события + * + * @return {Events} + */ +Events.prototype.findPastEvents = function () { + "use strict"; + + return this.filter(function (event) { + return event.get("timeStart") < new Date().getTime(); + }); +}; + +/** + * Предстоящие события + * + * @return {Events} + */ +Events.prototype.findFutureEvents = function () { + "use strict"; + + return this.filter(function (event) { + return event.get("timeStart") > new Date().getTime(); + }); +}; + +/** + * События с участием персоны с именем "name" + * + * @param personName Имя персоны + * + * @return {Events} + */ +Events.prototype.findEventsWithPerson = function (personName) { + "use strict"; + + return this.filter(function (event) { + return event.get("member").some(function (member) { + return member === personName; + }); + }); +}; + +/** + * События без участия персоны с именем "name" + * + * @param personName Имя персоны + * + * @return {Events} + */ +Events.prototype.findEventsWithoutPerson = function (personName) { + "use strict"; + + return this.filter(function (event) { + return event.get("member").every(function (member) { + return member != personName; + }); + }); +}; + +/** + * События, которые произойдут после указанного времени + * + * @param time Временной отсчет + * + * @return {Events} + */ +Events.prototype.findEventsHappendLaterTime = function (time) { + "use strict"; + + return this.filter(function (event) { + return event.get("timeStart") > time; + }); +}; + +/** + * События, которые произойдут до указанного времени + * + * @param time Временной отсчет + * + * @return {Events} + */ +Events.prototype.findEventsHappendBeforeTime = function (time) { + "use strict"; + + return this.filter(function (event) { + return event.get("timeStart") < time; + }); +}; + +/** + * Сортировка по времени начала события + * + * @return {Events} + */ +Events.prototype.sortEventsByDate = function () { + "use strict"; + + return this.sortBy("timeStart"); +}; + +/** + * Сортировка по рэтингу события + * + * @return {Events} + */ +Events.prototype.sortEventsByRaiting = function () { + "use strict"; + + return this.sortBy("raiting"); +}; + +/** + * Сортировка по имени события + * + * @return {Events} + */ +Events.prototype.sortEventsByName = function () { + "use strict"; + + return this.sortBy("name"); +}; \ No newline at end of file diff --git a/Event/Example.js b/Event/Example.js new file mode 100644 index 0000000..c3355d7 --- /dev/null +++ b/Event/Example.js @@ -0,0 +1,77 @@ +var myEvents = new Events([]) + .add(new Event("jsy6on0kz4", "7429kpz7nh", EventTime(new Date(2012, 10, 8), 45), ["Иванов", "я", "Петров"])) // 1 + .add(new Event("l8zklfh2r5", "1ygb121nee", EventTime(new Date(2012, 11, 22), 45), ["Иванов", "я"])) // 2 + .add(new Event("weoua5w3pf", "icu620fqpo", EventTime(new Date(2012, 11, 3), 45), ["Иванов"])) // 3 + .add(new Event("5zs4x4aij9", "4x9pkek4dp", EventTime(new Date(2012, 9, 10), 45), ["Иванов", "я", "Петров"])) // 4 + .add(new Event("s1m5vkm5mv", "5v6hifv041", EventTime(new Date(2012, 11, 25)), ["Иванов", "я"])) // 5 + .add(new Event("3bdg49u3ez", "zwvyu91w3b", EventTime(new Date(2012, 10, 10), 45), ["Иванов", "Петров"])) // 6 + .add(new Event("efc7dr20dx", "u641l89gw7", EventTime(new Date(2012, 9, 9)), ["Иванов", "я"])) // 7 + .add(new Event("pqlv9jglxq", "nkb24jd7u6", EventTime(new Date(2012, 10, 29)), ["Петров"])) // 8 + .add(new Event("iei2z6c63b", "kgzdrcs4mk", EventTime(new Date(2012, 11, 9)), ["я", "Петров"])) // 9 + .add(new Event("kygauxe4ub", "br0vzaikwr", EventTime(new Date(2012, 11, 27), 45), ["Иванов", "я"], 5)) // 10 + .add(new Event("ke4vd03xp8", "9k3bbogzz5", EventTime(new Date(2012, 11, 3), 45), ["Иванов"])) // 11 + .add(new Event("jt4kew1ayg", "4q51wfulmd", EventTime(new Date(2012, 11, 29), 45), ["Иванов", "Петров"])) // 12 + .add(new Event("dg9q72wmw9", "c5r5t5z024", EventTime(new Date(2012, 11, 8), 45), ["Иванов"])) // 13 + .add(new Event("v4873m9tgp", "l0rdqy22d3", EventTime(new Date(2012, 10, 25), 45), ["Иванов", "я"])) // 14 + .add(new Event("rrb6bjyubc", "0oxvmk59p4", EventTime(new Date(2012, 10, 23)), ["Иванов", "я"])) // 15 + .add(new Event("0oqqd4j655", "rb1gc65t8d", EventTime(new Date(2012, 10, 11), 45), ["Иванов", "Петров"])) // 16 + .add(new Event("f7b16x9cmy", "ncxmyqnhp1", EventTime(new Date(2012, 11, 4)), ["Иванов", "я"])) // 17 + .add(new Event("ik3xyzqoky", "3cguxe6l6n", EventTime(new Date(2012, 11, 16)), ["Петров"])) // 18 + .add(new Event("u4mfqatngu", "a7vnsmnpb0", EventTime(new Date(2012, 9, 24)), ["я"])) // 19 + .add(new Event("s53m0j6u9j", "bk9y4szr2s", EventTime(new Date(2012, 9, 7), 45), ["Иванов", "я"], 5)) // 20 + .add(new Event("lkajbmx7y2", "vwzpu1xl0o", EventTime(new Date(2012, 9, 20), 45), ["Иванов", "я", "Петров"], 1)); // 21 + +/** +* Все предстоящие события с моим участием отсортированные по рейтигу +*/ +function NewEventWithMeSortByRaiting() { + "use strict"; + + myEvents + .findFutureEvents() + .findEventsWithPerson("я") + .sortEventsByRaiting() + .items.forEach(printEvent); +} + +/** +* Все события, которые произойдут на этой неделе, отсортированые по рейтингу +*/ +function ThisWeekSortedByRaiting() { + "use strict"; + + var now = new Date(); + var today = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime(); + var timeToEndOfWeek = (7 - now.getDay()) * 24 * 60 * 60 * 1000; + var endOfWeek = new Date(today + timeToEndOfWeek); + myEvents + .findFutureEvents() + .findEventsHappendBeforeTime(endOfWeek) + .sortEventsByRaiting() + .items.forEach(printEvent); +}; + +/** +* Выбрать ближайшее (по времени) событие без моего участия +*/ +function FirstEventWithoutMe() { + "use strict"; + var filteredEvents = myEvents + .findFutureEvents() + .findEventsWithoutPerson("я") + .sortEventsByDate() + .items; + if (filteredEvents.length != 0) + printEvent(filteredEvents[0]); +}; + +var printEvent = function (event) { + console.log( + "Наименование: " + event.name + + " по адресу: " + event.address + + " начало в: " + event.timeStart + + " будет длится: " + event.timeLength + + " участники: " + event.member + + " рэйтинг: " + event.raiting + ); +} \ No newline at end of file diff --git a/Inherits.js b/Inherits.js new file mode 100644 index 0000000..3cc478b --- /dev/null +++ b/Inherits.js @@ -0,0 +1,7 @@ +function inherits (Constructor, SuperConstructor) { + "use strict"; + + var Temp = function () {}; + Temp.prototype = SuperConstructor.prototype; + Constructor.prototype = new Temp(); +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..63dd66d --- /dev/null +++ b/index.html @@ -0,0 +1,18 @@ + + +
+Выбрать все предстоящие события с моим участием отсортированные по рейтигу
+Выбрать все события, которые произойдут на этой неделе, отсортированые по рейтингу
+Выбрать ближайшее (по времени) событие без моего участия
+ + \ No newline at end of file