Flutter Http Request 从 JSON 响应中删除重复项

Posted

技术标签:

【中文标题】Flutter Http Request 从 JSON 响应中删除重复项【英文标题】:Flutter Http Request remove duplicates from JSON response 【发布时间】:2021-02-27 18:29:06 【问题描述】:

我按照教程 https://www.digitalocean.com/community/tutorials/flutter-flutter-http 制作了一个应用程序,该应用程序向 API 端点发送 get 请求并返回 JSON 响应。

JSON 响应如下所示:

["Order":"order1","Driver":"Driver1","Company":"Company1","Address":"Address1","Order":"order2","Driver":"Driver1","Company":"Company2","Address":"Address2","Order":"order3","Driver":"Driver1","Company":"Company3","Address":"Address3","Order":"order4","Driver":"Driver1","Company":"Cpmpany4","Address":"Address4","Order":"order5","Driver":"Driver1","Company":"Company5","Address":"Address5","Order":"order6","Driver":"Driver2","Company":"Company6","Address":"Address6","Order":"order7","Driver":"Driver2","Company":"Company7","Address":"Address7","Order":"order8","Driver":"Driver2","Company":"Company8","Address":"Address8","Order":"order9","Driver":"Driver2","Company":"Company9","Address":"Address9","Order":"order10","Driver":"Driver2","Company":"Company10","Address":"Address10","Order":"ord0439506","Driver":"Driver3","Company":"Company11","Address":"Address11","Order":"ord0439517","Driver":"Driver3","Company":"Company12","Address":"Address12","Order":"ord0439508","Driver":"Driver3","Company":"Company13","Address":"Address13"]

http_service.dart

class HttpService 
final String postsURL = "https://myapi:8080/getOrders";

Future<List<Post>> getPosts() async 
  Response res = await get(postsURL);

  if (res.statusCode == 200) 
    List<dynamic> body = jsonDecode(res.body);

    List<Post> posts = body
      .map(
        (dynamic item) => Post.fromJson(item),).toList();
      )
      .toList();

    return posts;
   else 
    throw "Can't get posts.";
  
 

posts_model.dart

import 'package:flutter/foundation.dart';

class Post 
  final String order;
  final String driver;
  final String company;
  final String address;

Post(
  @required this.order,
  @required this.driver,
  @required this.company,
  @required this.address,
);

factory Post.fromJson(Map<String, dynamic> json) 
  return Post(
    order: json['Order'] as String,
    id: json['Driver'] as String,
    title: json['Company'] as String,
    body: json['Address'] as String,
  );


posts.dart

 class PostsPage extends StatelessWidget 
     final HttpService httpService = HttpService();


     @override
     Widget build(BuildContext context) 
       return Scaffold(
         appBar: AppBar(
           title: Text("Orders"),
     ),
        body: FutureBuilder(
        future: httpService.getPosts(),
        builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot)
      if(snapshot.hasData)
        List<Post> posts = snapshot.data;

        return ListView( 
          children: posts
              .map(
                  (Post post) => ListTile(
                    title: Text(post.driver),
                      trailing: Icon(Icons.keyboard_arrow_right),
                  ),
          )
              .toList(),
        );
      

      return Center(
          child: CircularProgressIndicator());
    ,
  ));


ma​​in.dart

void main() => runApp(MyApp());

class MyApp extends StatelessWidget 
   @override
   Widget build(BuildContext context) 
      return MaterialApp(
        title: 'HTTP',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
           primarySwatch: Colors.blue,
     home: PostsPage(),
     );
   

当应用完成对我的 API 的发布请求时,它会将驱动程序显示为

驱动程序 1 驱动程序 1 驱动程序 1 驱动程序 1 驱动程序 2 驱动程序 2 驱动程序 2 驱动程序 2 驱动程序 3 驱动程序 3 驱动程序 3

我希望视图只显示每个驱动程序一次,因此没有重复

驱动程序 1 驱动程序 2 驱动程序 3

根据研究,大多数人说要将列表变成一个集合,我尝试在 posts.dart 中将 .toSet() 添加到 .toList() 但仍然显示重复项。我已经搞砸了一段时间,但仍然无法弄清楚。任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

假设您只想要驱动程序的名称,您可以执行类似遍历列表并将名称添加到另一个列表(如果它不存在)的操作

class PostsPage extends StatelessWidget 
     final HttpService httpService = HttpService();

     List<String> getDrivers(List<Post> posts) 
         List<String> res = [];
         posts.forEach((e) => if(!res.contains(e.driver)) res.add(e.driver));

         return res;
      

     @override
     Widget build(BuildContext context) 
       return Scaffold(
         appBar: AppBar(
           title: Text("Orders"),
     ),
        body: FutureBuilder(
        future: httpService.getPosts(),
        builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot)
      if(snapshot.hasData)
        List<Post> posts = snapshot.data;
        List<String> drivers = getDrivers(posts);

        return ListView( 
          children: drivers
              .map(
                  (driver) => ListTile(
                    title: Text(driver),
                      trailing: Icon(Icons.keyboard_arrow_right),
                  ),
          )
              .toList(),
        );
      

      return Center(
          child: CircularProgressIndicator());
    ,
  ));


【讨论】:

正是我想要的。谢谢。

以上是关于Flutter Http Request 从 JSON 响应中删除重复项的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Flutter Web 上的 localhost API(node js express)获取 http 请求的响应 [重复]

Api Request 使用 Http 请求获取 get 方法。但不知道 Flutter 中的实际问题

如何将图像文件传递到 Flutter 中的 Http 请求(POST)正文?

Node.js——request/get实现评论功能

Flutter Bloc 框架 实现 HTTP + JSON 通讯

为 Flutter http 请求设置请求超时的正确方法?