collections - 使用多个对象字段/多个条件过滤 ArrayList
问题描述
所以我有一个过滤集合的有趣问题,我有一个数据类如下:
data class Route(
val id: Int,
val name: String,
val weeklyPrice: Double?,
val monthlyPrice: Double?,
val seasonalPrice: Double?,
)
我在 UI 中显示一个 ArrayList 并且用户能够根据路线是否具有“每周/每月/季节性”价格来过滤列表,请记住我使用的是复选框而不是单选按钮,因此用户可以过滤使用多个选项。IE。只有每周,或者每周和每月都这样。
我的问题是使用过滤器函数和谓词我一次只能基于一个属性进行过滤,如下所示:
routes.filter {
it.weeklyPrice != null
}
但有时我实际上会根据另一个条件过滤掉我想保留的值,例如,用户不想要每周价格的路线,所以我过滤掉那些,但他想要那些每月价格的路线,但其中一些已经被过滤了基于他们也有每周价格的事实。
任何帮助将不胜感激,我相信它可以完成我只是还没弄清楚如何,也许问题在于首先如何表示数据?我不知道。
非常感谢提前。
解决方案
一种方法是生成过滤器列表,例如List<(Route) -> Boolean>
,然后在过滤器列表更改时使您的视图无效。
因此,例如,您有类似的东西:
// Use your own logic based on user selection here
private fun generateFilters() = listOf<(Route) -> Boolean>(
{ it.id != 0 },
{ it.weeklyPrice != null }
)
然后,根据这组过滤器生成你的视图,即:
private fun filterRoutes(routes: List<Route>, filters: List<(Route) -> Boolean>) =
routes.filter { route -> filters.all { filter -> filter(route) }
你甚至可以添加一个扩展函数List<T>
来提供一个filterAll
功能,比如:
private fun <T> List<T>.filterAll(filters: List<(T) -> Boolean>) =
filter { item -> filters.all { filter -> filter(item) } }
然后你的视图逻辑就变成了:
routers.filterAll(generateFilters())
推荐阅读
- c# - 在运行时将带有绑定的控件添加到 Xamarin ListView?
- sql - 在sql中每15分钟选择一次行
- javascript - 同一文件中的for循环,while循环和递归方法的结果不同?
- linux - 当我在终端中键入 mongodb 命令时,终端正在退出
- jquery - TinyMCE with AJAX content in cloned JQuery UI Dialog
- arrays - 数组在读取 React 中的状态时更新其所有元素 - Typescript
- unit-testing - 使用 Appium 和 Visual Studios 的 UI 测试没有获得按钮
- arrays - 如何按快速数组分组?
- html - 无法在字符串 Angular 上创建属性
- python - 我的json作为输出字符串而不是python中的int