如何访问 Dart 中的对象列表中的对象列表

Posted

技术标签:

【中文标题】如何访问 Dart 中的对象列表中的对象列表【英文标题】:How to access list of objects inside a list of Objects in Dart 【发布时间】:2021-05-24 20:34:48 【问题描述】:

创建具有类型的选项卡并需要在相应的TabView中显示..

 var listOfItem = [
    
      "types": "AR***",
      "restaurants": [
        
          "name": "ZauZau Restaurants",
          "location": "Mascat, Oman",
          "kms": "1.0 kms"
        ,
        
          "name": "MauMau Restaurants",
          "location": "Calicut, Oman",
          "kms": "2.0 kms"
        ,
        
          "name": "ChaCha Restaurants",
          "location": "Charat, Oman",
          "kms": "2.5 kms"
        ,
      ]
    ,
    
      "types": "COFFEE SHOP",
      "restaurants": [
        
          "name": "ZauZau Restaurants",
          "location": "Mascat, Oman",
          "kms": "1.0 kms"
        ,
      ]
    ,
  ];

这是我的物品清单 我通过

访问它的“餐厅”
listOfItem.asMap().entries.map((e) => print(e.value['restaurants'])).toList();

我需要映射那个特定的列表 试了很久。我对此没有任何想法 顺便说一句,我是编码新手..

【问题讨论】:

【参考方案1】:

快速解答

您可以嵌套两个 JSON 数据映射:

listOfItem.map((category) => Column(
  children: (category['restaurants'] as List<Map<String, dynamic>>)
      .map((restaurant) => Text(restaurant['name'])).toList()
).toList();

记住使用toList() 作为map 操作不会返回List,而是返回Iterable

基本完整解决方案

这是基于您的数据和Flutter Tabs 的第一个解决方案。

完整源代码:

import 'package:flutter/material.dart';

void main() 
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    ),
  );


class HomePage extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return DefaultTabController(
      length: data.length,
      child: Scaffold(
        appBar: AppBar(
          title: Text('Restaurants'),
          bottom: TabBar(
            tabs: data.map((category) => Tab(text: category['types'])).toList(),
          ),
        ),
        body: TabBarView(
          children: data
              .map((category) => ListView(
                    children:
                        (category['restaurants'] as List<Map<String, dynamic>>)
                            .map(
                              (restaurant) => ListTile(
                                title: Text(restaurant['name']),
                                subtitle: Text(restaurant['location']),
                              ),
                            )
                            .toList(),
                  ))
              .toList(),
        ),
      ),
    );
  


final data = [
  
    "types": "AR***",
    "restaurants": [
      
        "name": "ZauZau Restaurants",
        "location": "Mascat, Oman",
        "kms": "1.0 kms"
      ,
      
        "name": "MauMau Restaurants",
        "location": "Calicut, Oman",
        "kms": "2.0 kms"
      ,
      
        "name": "ChaCha Restaurants",
        "location": "Charat, Oman",
        "kms": "2.5 kms"
      ,
    ]
  ,
  
    "types": "COFFEE SHOP",
    "restaurants": [
      
        "name": "ZauZau Restaurants",
        "location": "Mascat, Oman",
        "kms": "1.0 kms"
      ,
    ]
  ,
];

高级完整解决方案

这是第二个解决方案,提供完全相同的视觉效果,但管理特定的域实体Restaurant & RestaurantCategory

它引入了状态管理和 JSON 序列化等概念。

完整源代码:

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

part '66318447.tabs.freezed.dart';
part '66318447.tabs.g.dart';

void main() 
  runApp(
    ProviderScope(
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
        home: HomePage(),
      ),
    ),
  );


class HomePage extends HookWidget 
  @override
  Widget build(BuildContext context) 
    final data = useProvider(dataProvider).state;
    return DefaultTabController(
      length: data.length,
      child: Scaffold(
        appBar: AppBar(
          title: Text('Restaurants'),
          bottom: TabBar(
            tabs: data.map((category) => Tab(text: category.name)).toList(),
          ),
        ),
        body: TabBarView(
          children: data
              .map((category) => ListView(
                    children: category.restaurants
                        .map(
                          (restaurant) => ListTile(
                            title: Text(restaurant.name),
                            subtitle: Text(
                                '$restaurant.location ($restaurant.kms away)'),
                          ),
                        )
                        .toList(),
                  ))
              .toList(),
        ),
      ),
    );
  


final dataProvider = StateProvider<List<RestaurantCategory>>(
    (ref) => data.map((json) => RestaurantCategory.fromJson(json)).toList());

@freezed
abstract class Restaurant with _$Restaurant 
  const factory Restaurant(String name, String location, String kms) =
      _Restaurant;

  factory Restaurant.fromJson(Map<String, dynamic> json) =>
      _$RestaurantFromJson(json);


@freezed
abstract class RestaurantCategory with _$RestaurantCategory 
  const factory RestaurantCategory(String name, List<Restaurant> restaurants) =
      _RestaurantCategory;

  factory RestaurantCategory.fromJson(Map<String, dynamic> json) =>
      _$RestaurantCategoryFromJson(json);


final data = [
  
    "name": "AR***",
    "restaurants": [
      
        "name": "ZauZau Restaurants",
        "location": "Mascat, Oman",
        "kms": "1.0 kms"
      ,
      
        "name": "MauMau Restaurants",
        "location": "Calicut, Oman",
        "kms": "2.0 kms"
      ,
      
        "name": "ChaCha Restaurants",
        "location": "Charat, Oman",
        "kms": "2.5 kms"
      ,
    ]
  ,
  
    "name": "COFFEE SHOP",
    "restaurants": [
      
        "name": "ZauZau Restaurants",
        "location": "Mascat, Oman",
        "kms": "1.0 kms"
      ,
    ]
  ,
];

【讨论】:

【参考方案2】:

试试这个循环:

for (final x in listOfItem)
    //x is the current object here
    for (final y in x["restaurants"])
        //y is the current restaurant
        print(y["property you want"]);
    

【讨论】:

那么,您可以使用类似的循环在餐厅中循环并检索属性: for (final x in listOfItem) for (final y in x["restaurants"]) print( y); 我看到我在注释中的代码可读性不是很好。所以我会编辑答案。 谢谢,是的,解决方案是嵌套循环。如果您解决了问题,能否将我的答案标记为解决方案?

以上是关于如何访问 Dart 中的对象列表中的对象列表的主要内容,如果未能解决你的问题,请参考以下文章

Flutter/Dart:如何访问地图/对象中的单个条目

迭代列表对象的行,如何访问整行?

如何访问适配器类中的 Activity 对象

如何在Dart中合并列表

反应如何访问 JSON 文件中的对象

C# 使用对象列表中的对象反序列化 JSON - 但无法访问它