Loading

的搜索结果

×
Loading...


闲聊大厅

AI眼中的完美代码……

Geticer

Geticer

1月前 15 举报

经过两个AI的来回指导和来回改善,这可能是最完美的代码了。

// TypeScript版本
interface Article {
  title: string;
  category: string;
}

class BlogArticles {
  private data: Article[];
  private filteredData: Article[];
  private cache: { [key: string]: Article[] };

  /**
   * 构造函数,初始化文章数据。
   * @param data - 文章数据数组。
   */
  constructor(data: Article[]) {
    if (!Array.isArray(data)) {
      throw new Error('Invalid data: expected an array of articles.');
    }

    // 验证每个文章对象
    for (const article of data) {
      if (typeof article.title !== 'string' || typeof article.category !== 'string') {
        throw new Error('Invalid article: each article must have a title and category.');
      }
    }

    this.data = data; // 原始数据
    this.filteredData = [...data]; // 使用扩展运算符复制数据
    this.cache = {}; // 用于缓存过滤结果
  }

  /**
   * 根据给定的标准筛选和分页数据。
   * @param criteria - 筛选标准,包括category, page, pagesize。
   * @returns 当前实例,支持链式调用。
   */
  filter(criteria: { category: string; page: number; pagesize: number }): this {
    const { category, page, pagesize } = criteria;
    if (typeof category !== 'string') {
      throw new Error('Invalid category: expected a string.');
    }
    if (typeof page !== 'number' || page < 1) {
      throw new Error('Invalid page: expected a positive integer.');
    }
    if (typeof pagesize !== 'number' || pagesize < 1) {
      throw new Error('Invalid pagesize: expected a positive integer.');
    }

    const cacheKey = `${category}-${page}-${pagesize}`;
    if (this.cache[cacheKey]) {
      this.filteredData = this.cache[cacheKey];
    } else {
      let filtered = this.data.filter(article => article.category === category);
      const start = (page - 1) * pagesize;
      const end = start + pagesize;
      this.filteredData = filtered.slice(start, end);
      this.cache[cacheKey] = this.filteredData;
    }
    return this; // 支持链式调用
  }

  /**
   * 清除缓存。
   * @returns 当前实例,支持链式调用。
   */
  clearCache(): this {
    this.cache = {};
    return this;
  }

  /**
   * 更新或添加文章数据。
   * @param newData - 新的文章数据数组。
   * @returns 当前实例,支持链式调用。
   */
  updateData(newData: Article[]): this {
    if (!Array.isArray(newData)) {
      throw new Error('Invalid data: expected an array of articles.');
    }

    // 验证每个文章对象
    for (const article of newData) {
      if (typeof article.title !== 'string' || typeof article.category !== 'string') {
        throw new Error('Invalid article: each article must have a title and category.');
      }
    }

    this.data = newData; // 更新原始数据
    this.clearCache(); // 清除缓存
    this.filteredData = [...newData]; // 更新筛选后的数据
    return this; // 支持链式调用
  }

  /**
   * 遍历筛选后的数据并执行回调函数。
   * @param callback - 每个元素上执行的回调函数。
   * @returns 当前实例,支持链式调用。
   */
  forEach(callback: (value: Article, index: number, array: Article[]) => void): this {
    if (typeof callback !== 'function') {
      throw new TypeError('Callback must be a function.');
    }

    try {
      this.filteredData.forEach(callback);
    } catch (error) {
      console.error('Error in forEach callback:', error);
    }
    return this; // 支持链式调用
  }

  /**
   * 对筛选后的数据进行排序。
   * @param compareFn - 比较函数,类似于Array.prototype.sort()的参数。
   * @returns 当前实例,支持链式调用。
   */
  sort(compareFn: (a: Article, b: Article) => number): this {
    if (typeof compareFn !== 'function') {
      throw new TypeError('Compare function must be a function.');
    }
    this.filteredData.sort(compareFn);
    return this; // 支持链式调用
  }

  /**
   * 执行回调函数,并保持链式调用的能力。
   * @param callback - 要执行的回调函数。
   * @returns 当前实例,支持链式调用。
   */
  execute(callback: () => void): this {
    if (typeof callback !== 'function') {
      throw new TypeError('Callback must be a function.');
    }

    try {
      callback.call(this); // 使用当前实例作为上下文执行callback
    } catch (error) {
      console.error('Error in execute callback:', error);
    }
    return this; // 支持链式调用
  }

  /**
   * 执行回调函数,但不返回当前实例(非链式调用)。
   * @param callback - 要执行的回调函数。
   */
  executeOnce(callback: () => void): void {
    if (typeof callback !== 'function') {
      throw new TypeError('Callback must be a function.');
    }

    try {
      callback.call(this); // 使用当前实例作为上下文执行callback
    } catch (error) {
      console.error('Error in executeOnce callback:', error);
    }
  }
}

// 示例使用
const xhrResponse = `[
  {"title": "Article 1", "category": "JS"},
  {"title": "Article 2", "category": "JS"},
  {"title": "Article 3", "category": "CSS"}
]`;

try {
  const blog = new BlogArticles(JSON.parse(xhrResponse));

  blog
    .filter({ category: 'JS', page: 1, pagesize: 2 }) // 筛选JS类别的前两篇文章
    .sort((a, b) => a.title.localeCompare(b.title)) // 按标题字母顺序排序
    .forEach((value, index, array) => { // 遍历筛选后的数据,创建HTML结构
      document.body.insertAdjacentHTML('beforeend', `<div>${value.title}</div>`);
    })
    .execute(() => { // 执行一些后续操作,比如打印日志
      console.log('第一页显示完成');
    })
    .execute(() => { // 调用Live2D的API(如果可用)
      Live2D?.getCurrentInstance()?.sayMessage('第一页');
    })
    .execute(() => { // 隐藏pace进度条(如果可用)
      pace?.hide?.();
    });
} catch (error) {
  console.error('Error initializing BlogArticles:', error);
}

// 单元测试示例
if (typeof describe === 'function') {
  describe('BlogArticles', () => {
    it('should filter and paginate correctly', () => {
      const data: Article[] = [
        { title: 'Article 1', category: 'JS' },
        { title: 'Article 2', category: 'JS' },
        { title: 'Article 3', category: 'CSS' }
      ];
      const blog = new BlogArticles(data);
      blog.filter({ category: 'JS', page: 1, pagesize: 2 });
      expect(blog.filteredData.length).toBe(2);
      expect(blog.filteredData[0].title).toBe('Article 1');
      expect(blog.filteredData[1].title).toBe('Article 2');
    });

    it('should clear the cache', () => {
      const data: Article[] = [
        { title: 'Article 1', category: 'JS' },
        { title: 'Article 2', category: 'JS' }
      ];
      const blog = new BlogArticles(data);
      blog.filter({ category: 'JS', page: 1, pagesize: 2 });
      blog.clearCache();
      expect(Object.keys(blog.cache).length).toBe(0);
    });

    it('should sort the filtered data', () => {
      const data: Article[] = [
        { title: 'B Article', category: 'JS' },
        { title: 'A Article', category: 'JS' }
      ];
      const blog = new BlogArticles(data);
      blog.filter({ category: 'JS', page: 1, pagesize: 2 }).sort((a, b) => a.title.localeCompare(b.title));
      expect(blog.filteredData[0].title).toBe('A Article');
      expect(blog.filteredData[1].title).toBe('B Article');
    });

    it('should handle errors in forEach and execute methods', () => {
      const data: Article[] = [
        { title: 'Article 1', category: 'JS' },
        { title: 'Article 2', category: 'JS' }
      ];
      const blog = new BlogArticles(data);

      // 测试 forEach 方法中的错误处理
      const originalConsoleError = console.error;
      console.error = jest.fn();
      blog.forEach((value, index, array) => {
        if (index === 1) {
          throw new Error('Test error in forEach');
        }
      });
      expect(console.error).toHaveBeenCalled();

      // 测试 execute 方法中的错误处理
      blog.execute(() => {
        throw new Error('Test error in execute');
      });
      expect(console.error).toHaveBeenCalledTimes(2);

      console.error = originalConsoleError;
    });
  });
}

最新回复 ( 0 )

目录