按优先级排序

Sorting by priority

提问人:Juan Carlos Estrella 提问时间:9/15/2023 最后编辑:Brian Tompsett - 汤莱恩Juan Carlos Estrella 更新时间:9/15/2023 访问量:21

问:

我需要你的帮助来排序应用一些规则。

我正在使用带有 prisma 的 nestjs,我有这两个模型。

model Prayer {
  id          Int       @id @default(autoincrement())
  title       String
  description String
  dueDate     DateTime?
  ongoing     Boolean
  answered    Boolean   @default(false)
  userId      Int
  contactId   Int?
  user        User      @relation(fields: [userId], references: [id])
  contact     Contact?  @relation(fields: [contactId], references: [id])
  createdAt   DateTime  @default(now())
}

model Note {
  id           Int       @id @default(autoincrement())
  title        String
  content      String
  userId       Int
  contactId    Int
  reminderDate DateTime?
  ongoing      Boolean?
  user         User      @relation(fields: [userId], references: [id])
  contact      Contact   @relation(fields: [contactId], references: [id])
  createdAt    DateTime  @default(now())
}

我需要创建一些逻辑来做到这一点:

  • 将音符(注)和祈祷(祈祷)放在同一水平上。

  • 优先级从设置为 true 的元素开始。

  • 如果有 2 个以上的元素将“正在进行”设置为 true“,请继续按最接近的提醒日期(”reminderDate“或”dueDate“,如适用)进行验证。

  • 如果没有将“正在进行”设置为 true“的元素,则还要按提醒日期(”reminderDate“或”dueDate“)进行计算。

  • 如果尽管进行了前面的验证,但仍有 2 个以上的元素,请继续通过“createdAt”进行验证。

  • 如果仍未选择 2 个元素,请按最接近的创建日期 (“createdAt”) 确定优先级。

  • 返回生成的 2 个元素,音符和祈祷的组合,或者只是音符或祈祷。

我创建了一个名为 UserFeed 的类:

import { Note, Prayer } from '@prisma/client';

export class UserFeed {
  notes: Note[];
  prayers: Prayer[];
}

我有这个

async getFeed(user: CurrentUser) {
    const allNotes = await this.prisma.note.findMany({
      where: {
        userId: user.sub,
      },
    });

    const allPrayers = await this.prisma.prayer.findMany({
      where: {
        userId: user.sub,
      },
    });

    const userFeed: UserFeed = this.applyPriorityAndSelection(
      allNotes,
      allPrayers,
    );

    return userFeed;
  }

  private applyPriorityAndSelection(
    notes: Note[],
    prayers: Prayer[],
  ): UserFeed {
    const feedDTO: UserFeed = { notes: [], prayers: [] };

    // Paso 1: Filtrar elementos con ongoing = true
    const ongoingNotes = notes.filter((note) => note.ongoing === true);
    const ongoingPrayers = prayers.filter((prayer) => prayer.ongoing === true);

    // Paso 2: Ordenar elementos con ongoing = true por reminderDate o dueDate más cercana
    ongoingNotes.sort((a, b) => {
      const dateA = a.reminderDate || a.createdAt;
      const dateB = b.reminderDate || b.createdAt;
      return dateB.getTime() - dateA.getTime();
    });

    ongoingPrayers.sort((a, b) => {
      const dateA = a.dueDate || a.createdAt;
      const dateB = b.dueDate || b.createdAt;
      return dateB.getTime() - dateA.getTime();
    });

    // Paso 3: Tomar los primeros 2 elementos con ongoing = true
    feedDTO.notes = ongoingNotes.slice(0, 2);
    feedDTO.prayers = ongoingPrayers.slice(0, 2);

    // Paso 4: Si no se han seleccionado 2 elementos con ongoing = true, ordenar por createdAt más cercano
    if (feedDTO.notes.length < 2) {
      const remainingNotes = notes.filter(
        (note) => !ongoingNotes.includes(note),
      );
      remainingNotes.sort(
        (a, b) => b.createdAt.getTime() - a.createdAt.getTime(),
      );
      feedDTO.notes.push(...remainingNotes.slice(0, 2 - feedDTO.notes.length));
    }

    if (feedDTO.prayers.length < 2) {
      const remainingPrayers = prayers.filter(
        (prayer) => !ongoingPrayers.includes(prayer),
      );
      remainingPrayers.sort(
        (a, b) => b.createdAt.getTime() - a.createdAt.getTime(),
      );
      feedDTO.prayers.push(
        ...remainingPrayers.slice(0, 2 - feedDTO.prayers.length),
      );
    }

    return feedDTO;
  }

但这给了我类似的东西:

{
  "data": {
    "feed": {
      "notes": [
        {
          "id": "45",
          "ongoing": true,
          "reminderDate": null,
          "createdAt": "2023-09-14T23:07:03.399Z"
        },
        {
          "id": "47",
          "ongoing": false,
          "reminderDate": null,
          "createdAt": "2023-09-14T23:18:13.385Z"
        }
      ],
      "prayers": [
        {
          "id": 32,
          "ongoing": true,
          "dueDate": null,
          "createdAt": "2023-09-12T23:53:38.617Z"
        },
        {
          "id": 29,
          "ongoing": true,
          "dueDate": null,
          "createdAt": "2023-09-12T23:42:51.929Z"
        }
      ]
    }
  }
}

我只需要两个对象,而不是每个对象两个。

有什么想法吗?

JavaScript TypeScript nestjs 优先级队列

评论


答: 暂无答案