Flutter - 在他们的父评论下排序评论回复

Flutter - Sort Comment Replies under their parent comment

我正在尝试对我的所有评论进行排序,以便回复将在他们的父评论下串接,在原始评论和他们的回复中从最旧到最新。

评论将有一个 ID、一个日期和一个可选的 parentId。

父评论将没有 parentId,而回复将具有父评论的 parentId。

我正在从 Firebase 获取数据并将其添加到列表中。

从该列表中,我将包含 parentId 的评论和不包含的评论分开。

final commentsWithoutParentID = comments
    .where(
        (c) => c.parentId.isEmpty,
    ).toList();

final commentsWithParentID = comments
   .where(
       (c) => c.parentId.isNotEmpty,
   ).toList();

然后我将它们排序为:

// Sort comments with no parent id by date
commentsWithoutParentID.sort((a, b) => a.date!.compareTo(b.date!));

// Sort comments with a parentId by date
commentsWithParentID.sort((a, b) => a.date!.compareTo(b.date!));

// Sort comments with a parentId by comparing the various parentId
commentsWithParentID.sort((a, b) => a.parentId.compareTo(b.parentId));

在此之后,我将这两个列表添加到一个空列表中:

sortedComments = commentsWithoutParentID + commentsWithParentID;

然后我对其进行排序以将 parentId 与 id 进行比较:

sortedComments.sort((a, b) => a.parentId.compareTo(b.id));

我得到的结果是,所有评论都按日期从最旧的顶部到最新的底部排序,并且一些回复在不正确的父评论下串连。

看来日期可能有更高的优先级。

我已经改变了这些排序,但我得到的结果与我现在得到的结果相同,或者与我想要的结果相差甚远。

当你在另一个排序之后调用排序时,你打破了之前的排序。

考虑组方法(需要 dart:collection 依赖项)。 或者你可以使用临时地图来分组 children.

import 'package:collection/collection.dart';

class Comment {
  final String date;
  final int id;

  Comment(this.date, this.id);

  @override
  String toString() => "($date, $id)";
}

class ThreadComment extends Comment {
  final int parentId;

  ThreadComment(String date, int id, this.parentId) : super(date, id);

  @override
  String toString() => "(parentId: $parentId, $date, $id)";
}

    final threadComments = [
      ThreadComment("day1", 1, 1),
      ThreadComment("day2", 4, 1),
      ThreadComment("day2", 3, 3),
      ThreadComment("day1", 2, 3),
    ];
    final parentComments = [
      Comment("day3", 5),
      Comment("day1", 1),
      Comment("day2", 3),
      Comment("day1", 2),
      Comment("day3", 4),
    ];
    
int compare(v1, v2) => v1.date.compareTo(v2.date);
final comments = <Comment, List<ThreadComment>>{};

// group comments by parent id
for (final Comment c
        in parentComments.sorted((a, b) => a.id.compareTo(b.id))) {
      comments[c] = threadComments
          .where((element) => element.parentId == c.id)
// sort children by date
          .sorted(compare);
    }
// sort parents by date
final sortedMap = comments.keys
        .toList()
        .sorted(compare)
        .asMap()
        .map((_, v) => MapEntry(v, comments[v]));

//expand map to one list
final sortedList = <List<Comment>>[
      for (final parent in sortedMap.keys) [parent, ...?sortedMap[parent]]
    ].expand((element) => element).toList();

sortedList.forEach((element) => print("$element\n"));

// (day1, 1)
// (parentId: 1, day1, 1)
// (parentId: 1, day2, 4)
// (day1, 2)
// (day2, 3)
// (parentId: 3, day1, 2)
// (parentId: 3, day2, 3)
// (day3, 4)
// (day3, 5)