【问题标题】:How to Iterate through nested json object array如何遍历嵌套的 json 对象数组
【发布时间】:2021-07-30 22:36:37
【问题描述】:

我对 Json 解析非常陌生。 我必须遍历 json 数组对象。

我的 JSON 类:

  class Jsons {
  static var hotelListJson = {
    'hotelData': [
      {
        'index': 0,
        'restaurantName': 'Monginis Cake Shop',
        'foodCategory': 'The Cake Shop',
        'restReview': 5,
        'restImage': 'assets/images/Restaurant1.png',
        'distanceFromLocation': 40,
        'restStatus': 'open',
        'menuCategories': [
          {
            'categoryName': 'Pastry',
            'dishes': [
              {
                'dishName': 'Dutch Pastry',
                'price': 5,
              },
              {
                'dishName': 'Black Forest pastry',
                'price': 50,
              },
              {
                'dishName': 'Truffle Pastry',
                'price': 35,
              },
              {
                'dishName': 'Dutch Alond Veg',
                'price': 50,
              },
            ]
          },

          {
            'categoryName': 'Breads',
            'dishes': [
              {
                'dishName': 'Sandwich Bread',
                'price': 5,
              },
              {
                'dishName': 'Multigrain Bread',
                'price': 50,
              },
              {
                'dishName': 'Duth Chocolate Heart Veg (Small)',
                'price': 35,
              },
              {
                'dishName': 'Brown Bread',
                'price': 50,
              },
            ]
          },

          
          {
            'categoryName': 'Savouries',
            'dishes': [
              {
                'dishName': 'Panner pattice',
                'price': 5,
              },
              {
                'dishName': 'Veg Burger',
                'price': 50,
              },
              {
                'dishName': 'Pan Pizza Veg',
                'price': 35,
              },
              {
                'dishName': 'Veg pattice',
                'price': 50,
              },
            ]
          },
        ]
      },
      {
        'index': 1,
        'restaurantName': 'Swami Hotel',
        'foodCategory': 'Family Hotel',
        'restReview': 2,
        'restImage': 'assets/images/Restaurant2.png',
        'distanceFromLocation': 40,
        'restStatus': 'open',
        'menuCategories': [
          {
            'categoryName': 'Veg Starter',
            'dishes': [
              {
                'dishName': 'Paneer pahadi kabab',
                'price': 5,
              },
              {
                'dishName': 'Garlic chana',
                'price': 50,
              },
              {
                'dishName': 'Masala papad',
                'price': 35,
              },
              {
                'dishName': 'Manchurian',
                'price': 50,
              },
              {
                'dishName': 'Masroom chilli',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'Non Veg Starter',
            'dishes': [
              {
                'dishName': 'CHI Chilli Gravy',
                'price': 5,
              },
              {
                'dishName': 'Lollypop Sezwan',
                'price': 50,
              },
              {
                'dishName': 'Pan Pizza Veg',
                'price': 35,
              },
              {
                'dishName': 'Chicken crispy',
                'price': 50,
              },
              {
                'dishName': 'Mandeli fry',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'Tandoori',
            'dishes': [
              {
                'dishName': 'Chicken Tandoori',
                'price': 5,
              },
              {
                'dishName': 'Chicken Tangadi Kabab',
                'price': 50,
              },
              {
                'dishName': 'Chicken Pahadi Kabab',
                'price': 35,
              },
              {
                'dishName': 'Chicken Hydrabadi Kabab',
                'price': 50,
              },
              {
                'dishName': 'Mutton Kadhai',
                'price': 50,
              },
            ]
          },
          
          {
            'categoryName': 'NON VEG SOUP',
            'dishes': [
              {
                'dishName': 'Chi manchaow Soup',
                'price': 5,
              },
              {
                'dishName': 'Chi Clear Soup',
                'price': 50,
              },
              {
                'dishName': 'Chi Schezwan Soup',
                'price': 35,
              },
              {
                'dishName': 'Swami Special Chi Soup',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'VEG SOUP',
            'dishes': [
              {
                'dishName': 'Chicken Masala',
                'price': 5,
              },
              {
                'dishName': 'Chicken Tikka Masala',
                'price': 50,
              },
              {
                'dishName': 'Chicken Handi',
                'price': 35,
              },
              {
                'dishName': 'Butter Chicken',
                'price': 50,
              },
              {
                'dishName': 'Mutton Kadhai',
                'price': 50,
              },
            ]
          },
        ]
      },
      {
        'index': 2,
        'restaurantName': 'Smart open pick cake shop',
        'foodCategory': 'Cake Shop',
        'restReview': 1,
        'restImage': 'assets/images/Restaurant4.png',
        'distanceFromLocation': 10,
        'restStatus': 'closed',
        'offer': 'Get 5% discount',
        'menuCategories': [
          {
            'categoryName': 'CAKE HALF Kg',
            'dishes': [
              {
                'dishName': 'Black Forest',
                'price': 300,
              },
              {
                'dishName': 'Pineapple half kg',
                'price': 50,
              },
              {
                'dishName': 'Lichi half kg',
                'price': 35,
              },
              {
                'dishName': 'choco chips half kg',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'CAKE 1 KG',
            'dishes': [
              {
                'dishName': 'Butterscotch',
                'price': 5,
              },
              {
                'dishName': 'Rose falooda',
                'price': 50,
              },
              {
                'dishName': 'White forest ovenpick',
                'price': 35,
              },
              {
                'dishName': 'Mix Fruit',
                'price': 50,
              },
            ]
          },
        ]
      },
      {
        'index': 3,
        'restaurantName': 'Mitarth Chinese',
        'foodCategory': 'Chinese corner',
        'restReview': 3,
        'restImage': 'assets/images/Restaurant5.png',
        'distanceFromLocation': 20,
        'restStatus': 'open',
      },
      {
        'index': 4,
        'restaurantName': 'Selfie Chat',
        'foodCategory': 'Paani Puri & more',
        'restReview': 2,
        'restImage': 'assets/images/Restaurant6.png',
        'distanceFromLocation': 40,
        'restStatus': 'open',
      },
      {
        'index': 5,
        'restaurantName': 'Gareeb Nawaj Biryani',
        'foodCategory': 'Caterers Biryani',
        'restReview': 5,
        'restImage': 'assets/images/Restaurant7.png',
        'distanceFromLocation': 40,
        'restStatus': 'open',
      },
      {
        'index': 6,
        'restaurantName': 'Prem Sweets',
        'foodCategory': 'Sweets shop',
        'restReview': 1,
        'restImage': 'assets/images/Restaurant8.png',
        'distanceFromLocation': 40,
        'restStatus': 'closed',
        'offer': 'Get 5% discount',
      }
    ]
  };
}

基本上我正在做的是 abc 是一家酒店的名称,并且其中填充了 abc 的子类别列表。subCategory 也有类型列表。

问题是该酒店下可能有很多类型。所以我需要一个合适的 Dart 循环结构,它可以通用来处理它。

我已经成功解析了主数组,但是我无法解析子类别和子类别下的类型。

这就是我的迭代方式:

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < (Jsons.hotelListJson['hotelData'].length); i++) {
      var currObj = Jsons.hotelListJson['hotelData'][i];
      var currObjSubCategoryList =
          currObj['menuCategories'] as List<Map<String, Object>>;
      for (int j = 0; j < currObjSubCategoryList.length; j++) {
        var listItem = currObjSubCategoryList[j];
        var typeList = listItem['categoryName'] as List<Map<String, Object>>;
        for (int k = 0; k < typeList.length; k++) {
          var temp = typeList[k];
          var currTypeName = temp['dishes'];
          print(currTypeName);
          restaurantListModel.add(RestaurantListModel(
            currObj['restaurantName'],
            currObj['foodCategory'],
            currObj['restReview'],
            currObj['restImage'],
            currObj['distanceFromLocation'],
            currObj['restStatus'],
          ));
        }
      }
    }
  }

这是我的模型类:

class RestaurantListModel {
  var name,
      category,
      review,
      offer;
  final List<String> menuCategory;

  RestaurantListModel(
      this.restaurantName,
      this.foodCategory,
      this.restReview,
      this.restImage,
      this.distanceFromLocation,
      this.restStatus,
      this.menuCategory,
      {this.offer});

}

我的容器:

Container(
              //height: MediaQuery.of(context).size.height - 450,
              child: NotificationListener<OverscrollIndicatorNotification>(
                onNotification: (overscroll) {
                  overscroll.disallowGlow();
                },
                child: ListView.builder(
                    padding: EdgeInsets.only(
                        top: 10, bottom: 30, left: 15, right: 15),
                    controller: ScrollController(),
                    shrinkWrap: true,
                    itemCount: restaurantListModel.length,
                    itemBuilder: (context, index) {
                      return RestaurantCard(restaurantListModel, index,
                          restaurantListModel[index]);
                    }),
              ),
            )

在 RestaurantCard 类中: 这就是我显示数据的方式:

              Padding(
              padding: const EdgeInsets.all(3.0),
              child: Container(
                alignment: Alignment.centerLeft,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      widget.restaurantListModelObj.restaurantName,
                      style: commonTextStyle(
                          size: 2.4 * SizeConfig.textMultiplier,
                          whichFont: 'bold'),
                    ),
                    Text(
                      widget.restaurantListModelObj.foodCategory,
                      style: commonTextStyle(
                        size: 2 * SizeConfig.textMultiplier,
                      ),
                    )
                  ],
                ),
              ),
            ),

请帮忙

提前致谢。

【问题讨论】:

  • 如果 type 是一个列表,它有一个长度属性,你可以只做 hotelListJson[`myData`][i][`subCategory'][j]['type'][k] 并且你可以使用 map() function with 'type' array
  • 你能解释一下你的答案吗?

标签: json flutter dart


【解决方案1】:

这就是我迭代列表长度的意思,我添加了一个代码,您可以从中了解如何解析。

更新代码

class Jsons {
  static var hotelListJson = {
    'hotelData': [
      {
        'index': 0,
        'restaurantName': 'Monginis Cake Shop',
        'foodCategory': 'The Cake Shop',
        'restReview': 5,
        'restImage': 'assets/images/Restaurant1.png',
        'distanceFromLocation': 40,
        'restStatus': 'open',
        'menuCategories': [
          {
            'categoryName': 'Pastry',
            'dishes': [
              {
                'dishName': 'Dutch Pastry',
                'price': 5,
              },
              {
                'dishName': 'Black Forest pastry',
                'price': 50,
              },
              {
                'dishName': 'Truffle Pastry',
                'price': 35,
              },
              {
                'dishName': 'Dutch Alond Veg',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'Breads',
            'dishes': [
              {
                'dishName': 'Sandwich Bread',
                'price': 5,
              },
              {
                'dishName': 'Multigrain Bread',
                'price': 50,
              },
              {
                'dishName': 'Duth Chocolate Heart Veg (Small)',
                'price': 35,
              },
              {
                'dishName': 'Brown Bread',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'Savouries',
            'dishes': [
              {
                'dishName': 'Panner pattice',
                'price': 5,
              },
              {
                'dishName': 'Veg Burger',
                'price': 50,
              },
              {
                'dishName': 'Pan Pizza Veg',
                'price': 35,
              },
              {
                'dishName': 'Veg pattice',
                'price': 50,
              },
            ]
          },
        ]
      },
      {
        'index': 1,
        'restaurantName': 'Swami Hotel',
        'foodCategory': 'Family Hotel',
        'restReview': 2,
        'restImage': 'assets/images/Restaurant2.png',
        'distanceFromLocation': 40,
        'restStatus': 'open',
        'menuCategories': [
          {
            'categoryName': 'Veg Starter',
            'dishes': [
              {
                'dishName': 'Paneer pahadi kabab',
                'price': 5,
              },
              {
                'dishName': 'Garlic chana',
                'price': 50,
              },
              {
                'dishName': 'Masala papad',
                'price': 35,
              },
              {
                'dishName': 'Manchurian',
                'price': 50,
              },
              {
                'dishName': 'Masroom chilli',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'Non Veg Starter',
            'dishes': [
              {
                'dishName': 'CHI Chilli Gravy',
                'price': 5,
              },
              {
                'dishName': 'Lollypop Sezwan',
                'price': 50,
              },
              {
                'dishName': 'Pan Pizza Veg',
                'price': 35,
              },
              {
                'dishName': 'Chicken crispy',
                'price': 50,
              },
              {
                'dishName': 'Mandeli fry',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'Tandoori',
            'dishes': [
              {
                'dishName': 'Chicken Tandoori',
                'price': 5,
              },
              {
                'dishName': 'Chicken Tangadi Kabab',
                'price': 50,
              },
              {
                'dishName': 'Chicken Pahadi Kabab',
                'price': 35,
              },
              {
                'dishName': 'Chicken Hydrabadi Kabab',
                'price': 50,
              },
              {
                'dishName': 'Mutton Kadhai',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'NON VEG SOUP',
            'dishes': [
              {
                'dishName': 'Chi manchaow Soup',
                'price': 5,
              },
              {
                'dishName': 'Chi Clear Soup',
                'price': 50,
              },
              {
                'dishName': 'Chi Schezwan Soup',
                'price': 35,
              },
              {
                'dishName': 'Swami Special Chi Soup',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'VEG SOUP',
            'dishes': [
              {
                'dishName': 'Chicken Masala',
                'price': 5,
              },
              {
                'dishName': 'Chicken Tikka Masala',
                'price': 50,
              },
              {
                'dishName': 'Chicken Handi',
                'price': 35,
              },
              {
                'dishName': 'Butter Chicken',
                'price': 50,
              },
              {
                'dishName': 'Mutton Kadhai',
                'price': 50,
              },
            ]
          },
        ]
      },
      {
        'index': 2,
        'restaurantName': 'Smart open pick cake shop',
        'foodCategory': 'Cake Shop',
        'restReview': 1,
        'restImage': 'assets/images/Restaurant4.png',
        'distanceFromLocation': 10,
        'restStatus': 'closed',
        'offer': 'Get 5% discount',
        'menuCategories': [
          {
            'categoryName': 'CAKE HALF Kg',
            'dishes': [
              {
                'dishName': 'Black Forest',
                'price': 300,
              },
              {
                'dishName': 'Pineapple half kg',
                'price': 50,
              },
              {
                'dishName': 'Lichi half kg',
                'price': 35,
              },
              {
                'dishName': 'choco chips half kg',
                'price': 50,
              },
            ]
          },
          {
            'categoryName': 'CAKE 1 KG',
            'dishes': [
              {
                'dishName': 'Butterscotch',
                'price': 5,
              },
              {
                'dishName': 'Rose falooda',
                'price': 50,
              },
              {
                'dishName': 'White forest ovenpick',
                'price': 35,
              },
              {
                'dishName': 'Mix Fruit',
                'price': 50,
              },
            ]
          },
        ]
      },
      {
        'index': 3,
        'restaurantName': 'Mitarth Chinese',
        'foodCategory': 'Chinese corner',
        'restReview': 3,
        'restImage': 'assets/images/Restaurant5.png',
        'distanceFromLocation': 20,
        'restStatus': 'open',
      },
      {
        'index': 4,
        'restaurantName': 'Selfie Chat',
        'foodCategory': 'Paani Puri & more',
        'restReview': 2,
        'restImage': 'assets/images/Restaurant6.png',
        'distanceFromLocation': 40,
        'restStatus': 'open',
      },
      {
        'index': 5,
        'restaurantName': 'Gareeb Nawaj Biryani',
        'foodCategory': 'Caterers Biryani',
        'restReview': 5,
        'restImage': 'assets/images/Restaurant7.png',
        'distanceFromLocation': 40,
        'restStatus': 'open',
      },
      {
        'index': 6,
        'restaurantName': 'Prem Sweets',
        'foodCategory': 'Sweets shop',
        'restReview': 1,
        'restImage': 'assets/images/Restaurant8.png',
        'distanceFromLocation': 40,
        'restStatus': 'closed',
        'offer': 'Get 5% discount',
      }
    ]
  };
}

void main() {
  for (int i = 0; i < (Jsons.hotelListJson['hotelData']!.length); i++) {
    var currObj = Jsons.hotelListJson['hotelData']![i];
    if (currObj.containsKey('menuCategories')) {
          var currObjSubCategoryList =
        currObj['menuCategories'] as List<Map<String, Object>>;
      for (int j = 0; j < currObjSubCategoryList.length; j++) {
        var listItem = currObjSubCategoryList[j];
        var typeList = listItem['dishes']! as List<Map<String, Object>>;
        for (int k = 0; k < typeList.length; k++) {
          var temp = typeList[k];
          var currDishName = temp['dishName'];
          var currDishPrice = temp['price'];
          print("Name: " +
              currDishName.toString() +
              "\n" +
              " Price :" +
              currDishPrice.toString());
        }
      }
    }
  }
}

【讨论】:

  • 它告诉我The method 'length' isn't defined for the type 'Object'. j 循环的这个错误
  • 现在它显示The getter 'length' was called on null. Receiver: null Tried calling: length 错误,我什至没有迭代到主数组。
  • 我现在添加了完整的代码,我已经在 DartPad 上显示了输出
  • 得到错误This requires the 'non-nullable' language feature to be enabled. Try updating your pubspec.yaml to set the minimum SDK constraint to 2.12.0 or higher, and running 'pub get'. 尝试了所有东西,但对我没有任何作用
  • 它在 dartpad 上完全正确,但在我的 VS 代码中却没有
【解决方案2】:

您应该在每次要检查节点时使用原始 Object.entries 和 Object.keys。

我会在这里留下一个简短的例子:

const hotelListJSON = {
    "myData":
        [
            {
                'index':0,
                'name':'abc',
                'category':'ab',
                'review':5,
                'subCategory':
                [
                {
                 'catName': 'ab1',
                 'type':
                 [
                     {
                     'typeName':'t1',
                     'price':50,
                     }, 
                     {
                     'typeName':'t2',
                     'price':50,
                     }, 
                     {
                     'typeName':'t3',
                     'price':50,
                     }, 
                 ]
               }
               ]
            },
            
            {
                'index':1,
                'name':'abc1',
                'category':'dc',
                'review':5,
                'subCategory':
                [
                {
                 'catName': 'dc1',
                 'type':
                 [
                     {
                     'typeName':'dc',
                     'price':50,
                     }, 
                     {
                     'typeName':'dc',
                     'price':50,
                     }, 
                     {
                     'typeName':'dc',
                     'price':50,
                     }, 
                ]
                }
                ]
            },
        ]
     };
    };
    
    Object.keys(hotelListJSON).forEach((elem)=>{
      //here you have your first node
      console.log(elem);
      Object.keys(elem).forEach((elem2)=>{
      //here you have any object that is a nested object with its containing, if it is a simble element you just get the value
      console.log(elem2);
      )}
      })

使用此脚本,您可以随心所欲地深入。

如果您遇到任何问题,请告诉我。

祝你有美好的一天。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-08
    • 2018-05-13
    • 1970-01-01
    • 2020-07-25
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多