You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按AvailableService过滤嵌套结构的Restaurant对象并返回同类型对象

Filter Restaurant Object by AvailableService Properties in Flutter

问题背景

我现在有这样一组Dart类定义:

class Restaurant{ 
  List<Menu> menus; 
} 
class Menu { 
  List<SubMenu> subMenus; 
} 
class SubMenu { 
  AvailableService availableService; 
} 
class AvailableService { 
  bool collection; 
  bool delivery; 
  bool table; 
}

已经实例化了Restaurant restaurant = Restaurant();,数据加载完成后每个SubMenu的服务属性都不同。现在需要实现一个过滤功能,比如得到仅包含支持配送(delivery为true)的SubMenu的新Restaurant对象,该怎么处理呢?


解决思路 & 代码实现

核心思路是递归过滤每一层数据,同时创建新对象避免修改原数据(防止副作用)。我们需要依次处理Restaurant→Menu→SubMenu这三层结构,只保留符合条件的子项,并且过滤掉空的Menu(避免保留没有有效SubMenu的菜单)。

1. 针对配送服务的专属过滤方法

如果只需要过滤支持配送的项,可以直接写一个专用方法:

Restaurant filterRestaurantForDelivery(Restaurant original) {
  // 过滤所有Menu,只保留包含符合条件SubMenu的Menu
  List<Menu> filteredMenus = original.menus?.where((menu) {
    // 过滤当前Menu下的SubMenu,仅保留delivery为true的
    List<SubMenu> validSubMenus = menu.subMenus?.where((subMenu) {
      return subMenu.availableService?.delivery == true;
    }).toList() ?? [];

    // 如果过滤后还有有效SubMenu,就返回一个更新了subMenus的新Menu对象
    if (validSubMenus.isNotEmpty) {
      return Menu(subMenus: validSubMenus);
    }
    // 否则过滤掉这个Menu
    return null;
  }).whereType<Menu>().toList() ?? [];

  // 返回包含过滤后菜单的新Restaurant对象
  return Restaurant(menus: filteredMenus);
}

2. 通用过滤方法(支持任意服务条件)

如果需要灵活支持不同的过滤规则(比如过滤支持到店取餐、同时支持配送+到店等),可以把过滤条件抽成参数,让方法更通用:

Restaurant filterRestaurant(Restaurant original, bool Function(AvailableService) filterRule) {
  List<Menu> filteredMenus = original.menus?.where((menu) {
    List<SubMenu> validSubMenus = menu.subMenus?.where((subMenu) {
      // 用传入的规则判断是否保留当前SubMenu
      return filterRule(subMenu.availableService!);
    }).toList() ?? [];

    if (validSubMenus.isNotEmpty) {
      // 注意:如果你的Menu类有其他属性(比如name、id),这里要把这些属性也复制过来
      return Menu(subMenus: validSubMenus);
    }
    return null;
  }).whereType<Menu>().toList() ?? [];

  return Restaurant(menus: filteredMenus);
}
使用示例
// 过滤仅支持配送的Restaurant
Restaurant deliveryOnlyRestaurant = filterRestaurant(restaurant, (service) => service.delivery == true);

// 过滤仅支持到店取餐的Restaurant
Restaurant collectionOnlyRestaurant = filterRestaurant(restaurant, (service) => service.collection == true);

// 过滤同时支持配送和到店取餐的Restaurant
Restaurant dualServiceRestaurant = filterRestaurant(restaurant, (service) => service.delivery && service.collection);

注意事项

  • 空值处理:代码里用?? []处理了可能的空列表情况,你可以根据自己的业务逻辑调整空值判断(比如是否允许保留空Menu)
  • 对象不可变性:我们始终创建新的Menu和Restaurant对象,不会修改原实例的数据,避免了意外的副作用
  • 类属性扩展:如果你的Menu或Restaurant有其他业务属性(比如restaurantName、menuId等),记得在创建新对象时把这些属性一并复制,避免丢失数据

内容的提问来源于stack exchange,提问作者flutter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 04:37:44