|
|
@@ -1,10 +1,10 @@
|
|
|
-import Reminder from './Reminder';
|
|
|
+import Reminder from "./Reminder";
|
|
|
|
|
|
/**
|
|
|
* A grouping of reminders based on tag (case-insensitive)
|
|
|
*/
|
|
|
export interface RemindersGroupingByTag {
|
|
|
- [tag: string]: Reminder[];
|
|
|
+ [tag: string]: Reminder[];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -12,95 +12,137 @@ export interface RemindersGroupingByTag {
|
|
|
* @description Represents a handler that manages a list of reminders
|
|
|
*/
|
|
|
export default class RemindersHandler {
|
|
|
- private _reminders: Reminder[];
|
|
|
-
|
|
|
- /**
|
|
|
- * Creates a new RemindersHandler instance with no reminders.
|
|
|
- */
|
|
|
- constructor() {
|
|
|
- this._reminders = [];
|
|
|
+ private _reminders: Reminder[];
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates a new RemindersHandler instance with no reminders.
|
|
|
+ */
|
|
|
+ constructor() {
|
|
|
+ this._reminders = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the list of reminders added so far.
|
|
|
+ */
|
|
|
+ public get reminders(): Reminder[] {
|
|
|
+ // 返回 _reminders 數組的副本
|
|
|
+ return [...this._reminders];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates a new reminder and adds it to list of reminders.
|
|
|
+ * @param description - The full description of reminder
|
|
|
+ * @param tag - The keyword used to help categorize reminder
|
|
|
+ */
|
|
|
+ public addReminder(description: string, tag: string): void {
|
|
|
+ const newReminder = new Reminder(description, tag);
|
|
|
+
|
|
|
+ // 將新的提醒添加到陣列中
|
|
|
+ this._reminders.push(newReminder);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the reminder at specified index.
|
|
|
+ * @throws ReminderError if specified index is not valid
|
|
|
+ * @param index - The index of the reminder
|
|
|
+ */
|
|
|
+ public getReminder(index: number): Reminder {
|
|
|
+ if (!this.isIndexValid(index)) {
|
|
|
+ throw new Error("ReminderError: Invalid index");
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Returns the list of reminders added so far.
|
|
|
- */
|
|
|
- public get reminders(): Reminder[] {
|
|
|
- throw new Error("Not yet implemented");
|
|
|
+ return this._reminders[index];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns true if specified index is valid, false otherwise.
|
|
|
+ * @param index - The position of the reminder in list of reminders
|
|
|
+ */
|
|
|
+ public isIndexValid(index: number): boolean {
|
|
|
+ if (this.size() === 0) return false;
|
|
|
+ if (index < 0 || index + 1 > this.size()) return false;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the number of reminders added so far.
|
|
|
+ */
|
|
|
+ public size(): number {
|
|
|
+ return this._reminders.length;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Modifies the description of the reminder at a specified index.
|
|
|
+ * Silently ignores call if index is not valid.
|
|
|
+ * @param index - The index of the reminder
|
|
|
+ * @param description - The full description of reminder
|
|
|
+ * @param tag - The keyword used to help categorize reminder
|
|
|
+ */
|
|
|
+ public modifyReminder(index: number, description: string): void {
|
|
|
+ // 檢查索引是否有效
|
|
|
+ if (!this.isIndexValid(index)) {
|
|
|
+ return; // 如果索引無效,直接返回
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Creates a new reminder and adds it to list of reminders.
|
|
|
- * @param description - The full description of reminder
|
|
|
- * @param tag - The keyword used to help categorize reminder
|
|
|
- */
|
|
|
- public addReminder(description: string, tag: string): void {
|
|
|
- throw new Error("Not yet implemented");
|
|
|
+ // 獲取特定索引處的提醒
|
|
|
+ const reminder = this._reminders[index];
|
|
|
+
|
|
|
+ // 更新提醒的描述
|
|
|
+ reminder.description = description;
|
|
|
+
|
|
|
+ // 注意:不需要顯式地將更新後的提醒存回數組,
|
|
|
+ // 因為 JavaScript 中對象是通過引用傳遞的
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Toggle the completion status of the reminder at specified index.
|
|
|
+ * Silently ignores call if index is not valid.
|
|
|
+ * @param index - The index of the reminder
|
|
|
+ */
|
|
|
+ public toggleCompletion(index: number): void {
|
|
|
+ // 檢查索引是否有效
|
|
|
+ if (!this.isIndexValid(index)) {
|
|
|
+ return; // 如果索引無效,直接返回
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Returns the reminder at specified index.
|
|
|
- * @throws ReminderError if specified index is not valid
|
|
|
- * @param index - The index of the reminder
|
|
|
- */
|
|
|
- public getReminder(index: number): Reminder {
|
|
|
- throw new Error("Not yet implemented");
|
|
|
- }
|
|
|
+ // 獲取特定索引處的提醒
|
|
|
+ const reminder = this._reminders[index];
|
|
|
|
|
|
- /**
|
|
|
- * Returns true if specified index is valid, false otherwise.
|
|
|
- * @param index - The position of the reminder in list of reminders
|
|
|
- */
|
|
|
- public isIndexValid(index: number): boolean {
|
|
|
- if (this.size() === 0) return false;
|
|
|
- if (index < 0 || index + 1 > this.size()) return false;
|
|
|
- return true;
|
|
|
- }
|
|
|
+ // 切換提醒的完成狀態
|
|
|
+ reminder.toggleCompletion();
|
|
|
|
|
|
- /**
|
|
|
- * Returns the number of reminders added so far.
|
|
|
- */
|
|
|
- public size(): number {
|
|
|
- return this._reminders.length;
|
|
|
- }
|
|
|
+ // 同樣地,由於 JavaScript 中對象是通過引用傳遞的,
|
|
|
+ // 更改將會直接反映在 `_reminders` 數組中的對應對象上
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * Modifies the description of the reminder at a specified index.
|
|
|
- * Silently ignores call if index is not valid.
|
|
|
- * @param index - The index of the reminder
|
|
|
- * @param description - The full description of reminder
|
|
|
- * @param tag - The keyword used to help categorize reminder
|
|
|
- */
|
|
|
- public modifyReminder(index: number, description: string): void {
|
|
|
- throw new Error("Not yet implemented");
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * Returns a list of reminders that match the keyword
|
|
|
+ * All reminders with tags that match the search keyword exactly will be returned first.
|
|
|
+ * If none exist, then all reminders with descriptions that match the search keyword (even partially)
|
|
|
+ * are returned.
|
|
|
+ * @param keyword - Text to search for in description and tag
|
|
|
+ */
|
|
|
+ public search(keyword: string): Reminder[] {
|
|
|
+ const keywordLower = keyword.toLowerCase();
|
|
|
|
|
|
- /**
|
|
|
- * Toggle the completion status of the reminder at specified index.
|
|
|
- * Silently ignores call if index is not valid.
|
|
|
- * @param index - The index of the reminder
|
|
|
- */
|
|
|
- public toggleCompletion(index: number): void {
|
|
|
- throw new Error("Not yet implemented");
|
|
|
- }
|
|
|
+ // 首先根據標籤搜索
|
|
|
+ let results = this.searchTags(keywordLower);
|
|
|
|
|
|
- /**
|
|
|
- * Returns a list of reminders that match the keyword
|
|
|
- * All reminders with tags that match the search keyword exactly will be returned first.
|
|
|
- * If none exist, then all reminders with descriptions that match the search keyword (even partially)
|
|
|
- * are returned.
|
|
|
- * @param keyword - Text to search for in description and tag
|
|
|
- */
|
|
|
- public search(keyword: string): Reminder[] {
|
|
|
- throw new Error("Not yet implemented");
|
|
|
- }
|
|
|
+ // 如果沒有找到匹配的標籤,則根據描述搜索
|
|
|
+ if (results.length === 0) {
|
|
|
+ results = this.searchDescriptions(keywordLower);
|
|
|
+ }
|
|
|
+
|
|
|
+ return results;
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * Returns a grouping of the reminders based on tag (case-insensitive).
|
|
|
- */
|
|
|
- public groupByTag(): RemindersGroupingByTag {
|
|
|
- const groupings: RemindersGroupingByTag = {};
|
|
|
+ /**
|
|
|
+ * Returns a grouping of the reminders based on tag (case-insensitive).
|
|
|
+ */
|
|
|
+ public groupByTag(): RemindersGroupingByTag {
|
|
|
+ const groupings: RemindersGroupingByTag = {};
|
|
|
|
|
|
- /* Pseudocode:
|
|
|
+ /* Pseudocode:
|
|
|
You must group the reminders by tags.
|
|
|
So you need to take this._reminders which is currently like so:
|
|
|
|
|
|
@@ -115,23 +157,40 @@ export default class RemindersHandler {
|
|
|
}
|
|
|
|
|
|
*/
|
|
|
-
|
|
|
- return groupings;
|
|
|
- }
|
|
|
|
|
|
- /**
|
|
|
- * Returns a list of reminders with tags that match the keyword exactly.
|
|
|
- * @param keyword - Text to search for in description and tag
|
|
|
- */
|
|
|
- private searchTags(keyword: string): Reminder[] {
|
|
|
- throw new Error("Not yet implemented");
|
|
|
- }
|
|
|
+ // 遍歷所有提醒
|
|
|
+ for (const reminder of this._reminders) {
|
|
|
+ // 獲取標籤,並將其轉換為小寫以實現不區分大小寫
|
|
|
+ const tag = reminder.tag.toLowerCase();
|
|
|
+
|
|
|
+ // 如果該標籤還未在分組中則初始化
|
|
|
+ if (!groupings[tag]) {
|
|
|
+ groupings[tag] = [];
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * Returns a list of reminders with descriptions that match the keyword.
|
|
|
- * @param keyword - Text to search for in description and tag
|
|
|
- */
|
|
|
- private searchDescriptions(keyword: string): Reminder[] {
|
|
|
- throw new Error("Not yet implemented");
|
|
|
+ // 將提醒添加到相應標籤的分組中
|
|
|
+ groupings[tag].push(reminder);
|
|
|
}
|
|
|
+
|
|
|
+ return groupings;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns a list of reminders with tags that match the keyword exactly.
|
|
|
+ * @param keyword - Text to search for in description and tag
|
|
|
+ */
|
|
|
+ private searchTags(keyword: string): Reminder[] {
|
|
|
+
|
|
|
+ // 篩選出標籤匹配的提醒
|
|
|
+ return this._reminders.filter((reminder) => reminder.tag.toLowerCase() === keyword);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns a list of reminders with descriptions that match the keyword.
|
|
|
+ * @param keyword - Text to search for in description and tag
|
|
|
+ */
|
|
|
+ private searchDescriptions(keyword: string): Reminder[] {
|
|
|
+ // 篩選出描述中包含關鍵字的提醒
|
|
|
+ return this._reminders.filter((reminder) => reminder.description.toLowerCase().includes(keyword));
|
|
|
+ }
|
|
|
}
|