将嵌套对象组合到一个级别

问题描述 投票:0回答:2

在飞镖中我有下课

class PostComment {
  int id;
  int title;
  int parentCommentId;
  List<PostComment> replies;
}

我从api收到的数据返回单个数组中的所有注释(无论在什么级别)。 parentCommentId用于指向回复的父级。要将此数据转换为嵌套结构,我会这样做

void toNestedComments({List<PostComment> comments}) {
  comments.forEach((postComment) {
    if (postComment.parentCommentId != null) {
      PostComment parentComment = comments.firstWhere((comment) => comment.id == postComment.parentCommentId, orElse: () => null);
      parentComment.replies.add(postComment);
    }
  });

  comments.removeWhere((c) => c.parentCommentId != null);
}

使用此代码,我在下面的结构中获取了comments数组。

Post 1
    - Post 11
    - Post 12
        - Post 121
        - Post 122
    - Post 13
Post 2
    - Post 21
        - Post 211   

但是,UI要求数据显示如下。

Post 1
    - Post 11
    - Post 12
    - Post 121
    - Post 122
    - Post 13
Post 2
    - Post 21
    - Post 211  

您对上述功能建议进行哪种修改才能实现上述结构?

当前代码和数据结构位于https://dartpad.dartlang.org/6231828b3ea9dc1e956e87353394dae7

recursion dart reduce
2个回答
0
投票

我不完全确定您的数据结构,但我想您可以这样做:

像这样扩展PostComment类:

class PostComment {
  int id;
  int title;
  int parentCommentId;
  List<PostComment> replies = [];

  Iterable<PostComment> thisAndNestedReplies() sync* {
    yield this;
    for (var reply in replies) {
      yield* reply.thisAndNestedReplies();
    }
  }
}

然后你可以执行以下操作(我仍然使用你的方法来获取嵌套的数据结构):

toNestedComments(comments: comments);
var newList = comments
    .where((postComment) => postComment.parentCommentId == null)
    .expand((postComment) => postComment.thisAndNestedReplies()).toList();

-1
投票

PostComment实体中没有任何业务逻辑的解决方案。 函数main中数据查询中的所有逻辑。

import 'package:queries/collections.dart';

import 'dart:core';
import 'dart:convert';

void main() {
  var comments = Collection(getComments());
  var query = comments
      .groupJoin(
          comments,
          (o) => o.id,
          (i) => i.parentCommentId,
          (o, i) =>
              o..comments.addAll((i as IEnumerable<PostComment>).toList()))
      .where((p) => p.parentCommentId == null);
  printComments(query.toList(), 0);
}

void printComments(List<PostComment> comments, int indent) {
  for (var comment in comments) {
    var sb = StringBuffer();
    sb.write(''.padLeft(indent, '  '));
    sb.write(comment.id);
    print(sb);
    printComments(comment.comments, indent + 1);
  }
}

// Json with the all the comments. Replies to comment have parentCommentId set.
String json = '''
{
  "comments": [
    {
      "id": 35,
      "description": "Post 1",
      "parentCommentId": null
    },
    {
      "id": 36,
      "description": "Post 11",
      "parentCommentId": 35
    },
    {
      "id": 37,
      "description": "Post 111",
      "parentCommentId": 36
    },
    {
      "id": 38,
      "description": "Post 2",
      "parentCommentId": null

    },
    {
      "id": 39,
      "description": "Post 3",
      "parentCommentId": null
    },
    {
      "id": 61,
      "description": "Post 2",
      "parentCommentId": 35
    },
    {
      "id": 62,
      "description": "Post 21",
      "parentCommentId": 61
    },
    {
      "id": 64,
      "description": "Post 211",
      "parentCommentId": 62
    }
  ]
}
''';

List<PostComment> getComments() {
  var comments = <PostComment>[];
  final responseMap = jsonDecode(json);
  responseMap['comments'].forEach((i) {
    comments.add(PostComment.fromJson(i));
  });

  return comments;
}

class PostComment {
  PostComment({this.id, this.description, this.parentCommentId, this.postId});

  int id;
  String description;
  int parentCommentId;
  int postId;
  List<PostComment> comments;

  factory PostComment.fromJson(Map<String, dynamic> map) {
    final commentInfo = map;

    final _comment = PostComment(
      id: commentInfo['id'],
      description: commentInfo['description'],
      postId: commentInfo['postId'],
      parentCommentId: int.tryParse(commentInfo['parentCommentId'].toString()),
    );

    _comment.comments = List<PostComment>();
    return _comment;
  }

  String toString() {
    return this.description;
  }
}

结果:

35 36 37 61 62 64 38 39

P.S

此代码使用i as IEnumerable<PostComment>,因为目前Dart编译器无法推断数据类型。看起来像编译器中的错误。

© www.soinside.com 2019 - 2024. All rights reserved.