如果较低级别不匹配,则过滤器不会返回结果,除非高级级别匹配

问题描述 投票:0回答:1

下面的代码应该搜索章节名称、章节名称、小节名称或段落内容中的任何匹配项,但不幸的是,它仅在章节名称匹配时才返回结果,这意味着如果段落内容匹配,它将忽略整个内容章节,因为它与章节名称不匹配。下面是过滤代码:

override fun getFilter(): Filter {
        return object : Filter() {
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val query = constraint.toString().lowercase()
                searchTextQuery=query
                val filteredData = if (query.isEmpty()) {
                    originalList
                } else {
                    originalList.filter { chapter ->
                        chapter.name.lowercase().contains(query) ||
                                chapter.sectionList?.any { section ->
                                    section.name.lowercase().contains(query) ||
                                            section.subsectionList?.any { subsection ->
                                                subsection.name.lowercase().contains(query) ||
                                                        subsection.paragraphList?.any { 
paragraph->paragraph.name.lowercase().contains(query)
                                                        } == true
                                            } == true
                                } == true
                    }
                }

                val results = FilterResults()
                results.values = filteredData
                return results
       }

       override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                if (results!= null && results.values is List<*>) {
                    filteredList = results.values as List<Chapter>
                    notifyDataSetChanged()
                }
       }
   }
}```


Model is below ```@Parcelize
data class Book(
    @SerializedName("id") val id: String?,
    @SerializedName("title") val title: String,
    @SerializedName("chapters") var chapters: List<Chapter>?
): Parcelable

@Parcelize
data class Chapter(
    @SerializedName("id") val id: String?,
    @SerializedName("ctitle") var name: String,
    @SerializedName("sections") var sectionList: MutableList<Section>? = null,
    @SerializedName("bookId") var bookId: String?,
    @SerializedName("cnumber") var number: String?,
    var isExpanded: Boolean = false
):Parcelable

@Parcelize
data class Section(
    @SerializedName("id") val id: String?,
    @SerializedName("title") var name: String,
    @SerializedName("chapterId") var chapterId: String?,
    @SerializedName("sectionnum") var sectionnum: String?,
    @SerializedName("subsections") var subsectionList: MutableList<SubSection>? = null,
    @SerializedName("paragraphs") var paragraphList: MutableList<Paragraph>? = null,
    var cleanedParagraphs:MutableList<Paragraph>? = null,
    var isExpanded: Boolean = false
): Parcelable

@Parcelize
data class SubSection(
    @SerializedName("id") val id: String?,
    @SerializedName("title") var name: String,
    @SerializedName("chapterId") var chapterId: String?,
    @SerializedName("subsectionnum") var sectionnum: String?,
    @SerializedName("paragraphs") var paragraphList: MutableList<Paragraph>? = null,
    var cleanedParagraphs:MutableList<Paragraph>?= null,
    var isExpanded: Boolean = false
): Parcelable

@Parcelize
data class Paragraph(
    @SerializedName("content") var name: String,
    @SerializedName("sectionId") var sectionId: String?,
    @SerializedName("sectionnum") val sectionnum: String?,
    @SerializedName("subsectionId") var subsectionId: String?,
    var isExpanded: Boolean = false
):Parcelable```
android kotlin search
1个回答
0
投票

你正在短路情况。

chapter.name.lowercase().contains(query) ||

条件中的

||
只检查章节名称,不关心其余部分,因为它总是错误的。

你想要的是即使第一个要求失败后仍能继续搜索的东西。

    val filteredData = if (query.isEmpty()) {
                    originalList
                } else {
                    originalList.filter { chapter ->
                        doesChapterMatch(chapter, query)
                    }
                }

    fun doesChapterMatch(chapter: Chapter, query: String): Boolean {
        return if (chapter.name.contains(query)) {
            true
        } else {
            chapter.sectionList?.any { section -> doesSectionMatch(section, query) } == true
        }
    }

    fun doesSectionMatch(section: Section, query: String): Boolean {
        return if (section.name.contains(query)) {
            true
        } else {
            section.subsectionList?.any { subsection -> doesSubSectionMatch() } == true
        }
    }

    fun doesSubSectionMatch(subSection: SubSection, query: String): Boolean {
        return if (subSection.name.contains(query)) {
            true
        } else {
            subsection.paragraphList?.any { paragraph -> doesParagraphMath(paragraph, query) } == true
        }
    }

    fun doesParagraphMatch(paragraph: Paragraph, query: String): Boolean = paragraph.name.contains(query)
© www.soinside.com 2019 - 2024. All rights reserved.