筛选对象列表
Filter a list of object
假设我有一个对象列表:
data class Home(
var id: String = "",
var status: MutableMap<String, Double> = mutableMapOf(),
var userName: String = "",
)
var myList = listOf(
Home("1", mutableMapOf("hello", 1.0), "firstUser"),
Home("2", mutableMapOf("hello", 2.0), "secondUser"),
Home("3", mutableMapOf("goodbye", 3.0), "thirdUser")
)
有了这个列表,我想实现一个搜索视图,我想根据地图键或用户名过滤这个列表。例如,如果我搜索“hello”,它将 return 一个包含 2 个对象的列表:
listOf(Home("1", mutableMapOf("hello", 1.0), "firstUser"),
Home("2", mutableMapOf("hello", 2.0), "secondUser"))
我正在尝试以下代码但没有成功:
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
myList.stream()
.filter { p ->
p.userName.lowercase(Locale.getDefault())
.contains(newText.lowercase(Locale.getDefault())) ||
p.status.keys.contains(newText.lowercase(Locale.getDefault()))
}
.collect(Collectors.toList())
adapter.submitList(myList)
}
})
请问我做错了什么?
编辑:正如@Joffrey 所说,我修改了代码以便可以使用 Kotlin 过滤器。我正在按用户名过滤,没关系。当我尝试通过映射键过滤 myList 时,我必须插入整个文本才能得到任何结果,例如:“hello”。此时,如果地图的键包含子字符串,我需要过滤列表。
override fun onQueryTextChange(newText: String): Boolean {
val filteredList: List<Home> =
myList.filter {
it.userName.lowercase(Locale.getDefault()).contains(newText.lowercase(Locale.getDefault())) ||
it.status.keys.contains(newText)
}
adapter.submitList(filteredList)
return false
}
我已经这样解决了,下面的函数将找到列表中其键包含所需子字符串的每个地图:
infix fun <V> Map<String, V>.withKeyPart(keyPart: String): List<V> {
return this.filter { it.key.lowercase(Locale.getDefault()).contains(keyPart) }
.map { it.value }
}
然后应用我这样的搜索视图:
override fun onQueryTextChange(newText: String): Boolean {
val filteredList: List<Home> =
myList.filter {
it.userName.lowercase(Locale.getDefault()).contains(newText.lowercase(Locale.getDefault())) ||
it.status.withKeyPart(newText.lowercase(Locale.getDefault())).isNotEmpty()
}
adapter.myList(filteredList)
return false
}
假设我有一个对象列表:
data class Home(
var id: String = "",
var status: MutableMap<String, Double> = mutableMapOf(),
var userName: String = "",
)
var myList = listOf(
Home("1", mutableMapOf("hello", 1.0), "firstUser"),
Home("2", mutableMapOf("hello", 2.0), "secondUser"),
Home("3", mutableMapOf("goodbye", 3.0), "thirdUser")
)
有了这个列表,我想实现一个搜索视图,我想根据地图键或用户名过滤这个列表。例如,如果我搜索“hello”,它将 return 一个包含 2 个对象的列表:
listOf(Home("1", mutableMapOf("hello", 1.0), "firstUser"),
Home("2", mutableMapOf("hello", 2.0), "secondUser"))
我正在尝试以下代码但没有成功:
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
myList.stream()
.filter { p ->
p.userName.lowercase(Locale.getDefault())
.contains(newText.lowercase(Locale.getDefault())) ||
p.status.keys.contains(newText.lowercase(Locale.getDefault()))
}
.collect(Collectors.toList())
adapter.submitList(myList)
}
})
请问我做错了什么?
编辑:正如@Joffrey 所说,我修改了代码以便可以使用 Kotlin 过滤器。我正在按用户名过滤,没关系。当我尝试通过映射键过滤 myList 时,我必须插入整个文本才能得到任何结果,例如:“hello”。此时,如果地图的键包含子字符串,我需要过滤列表。
override fun onQueryTextChange(newText: String): Boolean {
val filteredList: List<Home> =
myList.filter {
it.userName.lowercase(Locale.getDefault()).contains(newText.lowercase(Locale.getDefault())) ||
it.status.keys.contains(newText)
}
adapter.submitList(filteredList)
return false
}
我已经这样解决了,下面的函数将找到列表中其键包含所需子字符串的每个地图:
infix fun <V> Map<String, V>.withKeyPart(keyPart: String): List<V> {
return this.filter { it.key.lowercase(Locale.getDefault()).contains(keyPart) }
.map { it.value }
}
然后应用我这样的搜索视图:
override fun onQueryTextChange(newText: String): Boolean {
val filteredList: List<Home> =
myList.filter {
it.userName.lowercase(Locale.getDefault()).contains(newText.lowercase(Locale.getDefault())) ||
it.status.withKeyPart(newText.lowercase(Locale.getDefault())).isNotEmpty()
}
adapter.myList(filteredList)
return false
}