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)
我正在尝试对我的所有评论进行排序,以便回复将在他们的父评论下串接,在原始评论和他们的回复中从最旧到最新。
评论将有一个 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)