簡體   English   中英

如何使用 swiftUI 中的數組實現搜索功能?

[英]How to implement search functionality with array of array in swiftUI?

我正在使用具有搜索功能的 swiftUI 我指的是https://www.appcoda.com/swiftui-search-bar/本教程但問題是我正在使用數組數組進行搜索功能

{
  "MainList": [
    {
      "id": "1",
      "SubList": [
        {
          "id": "326359",
          "system": "NNN",
          
        },
        {
          "id": "320909",
          "system": "PPP",
          
        }
      ],
      "organisationName": "Pizza"
    }
  ]
}

因此, SubList organisationName是它的相應行。

我努力了

List(orgList.filter({ searchText.isEmpty ? true : $0.name.contains(searchText) })) { item in
}

但是這樣我只能遍歷MainList並執行搜索,我不知道如何繼續使用SubList搜索 object。 已經嘗試過兩次ForEach但我的數據在 UI 中重復了..你能幫忙嗎?

所以簡而言之,我正在尋找帶有數組項數組的分段列表中的搜索欄。 :)

編輯:僅在SubList上的搜索功能

給這只貓剝皮的方法肯定不止一種。 當然,您可以單獨循環遍歷列表和子列表,手動構建結果列表。 我假設您知道如何做到這一點,並且更喜歡使用 Swift 標准庫為您完成大部分工作的方法。

方法細節將取決於 Swift 中數據的確切表示方式。 我將根據您對“數組數組”的描述提出一種解決方案,因為這就是您所要求的。 但接下來我將介紹一個基於 JSON 在 Swift 中更自然地解碼的內容。

Arrays 數組 - 使用flatMapfilter

大部分代碼實際上只是設置一些示例數據:

func searchArrayOfArray()
{
    struct SubListElement: CustomStringConvertible
    {
        let id: String
        let system: String
        
        var description: String { "{\(id), \(system)}" }
    }
    
    let mainList =
    [
        [
            SubListElement(id: "326359", system: "NNN"),
            SubListElement(id: "320909", system: "PPP"),
        ],
        [
            SubListElement(id: "123456", system: "NNN"),
            SubListElement(id: "789012", system: "XYZ")
        ],
    ]
    
    let results = mainList.flatMap { $0.filter { $0.system == "NNN" } }
    print("\(results)")
}

.flatMap遍歷嵌套的 collections 的元素。 基本上,它會將所有葉子元素收集到一個單一的平面列表中,如果您想從樹的角度來考慮它。 它在每個葉子元素上調用它的閉包。 在這種情況下,閉包調用.filter ,到 select 符合條件的葉子,在這種情況下, system屬性是"NNN" 當然,您可以用String變量代替硬編碼的搜索詞。

output 是

[{326359, NNN}, {123456, NNN}]

包含結構數組的結構數組 - 使用mapfilterflatmap

這更接近提供的 JSON 所代表的內容。 在這種情況下flatmap僅用於展平結果。 沒有它,你會得到一個 arrays 數組。

同樣,大部分代碼只是設置示例數據。

func searchArrayOfStructsContainingArrays()
{
    struct SubListElement: CustomStringConvertible
    {
        let id: String
        let system: String
        
        var description: String { "{\(id), \(system)}" }
    }

    struct MainListElement
    {
        let id: String
        let subList: [SubListElement]
        let organisationName: String
    }
    
    let mainList =
    [
        MainListElement(
            id: "1",
            subList:
            [
                SubListElement(id: "326359", system: "NNN"),
                SubListElement(id: "320909", system: "PPP")
            ],
            organisationName: "Pizza"
        ),
        MainListElement(
            id: "2",
            subList:
            [
                SubListElement(id: "123456", system: "NNN"),
                SubListElement(id: "789012", system: "XYZ")
            ],
            organisationName: "Calzone"
        )
    ]
    
    let results = mainList.map { $0.subList.filter { $0.system == "NNN" } }.flatMap { $0 }
    print("\(results)")
}

.map使用閉包轉換集合的每個元素。 在這種情況下,它將其轉換為通過在每個MainListElement.subList上調用.filter生成的集合,因此它將每個MainListElement轉換為其對應的[SubListElement] .filter在那些[SubListElement] arrays 到 select 上被調用,只有system等於"NNN"的那些。 但是,這給出了[[SubListElement]] ,需要將其展平為[SubListElement] ,所以這就是尾隨的.flatMap所做的。

這將產生與以前完全相同的 output。

獲取組織的整個子列表

問題中有一些證據表明,您可能想要的只是獲取組織的整個子列表。 我需要查看“數組數組”如何存儲組織名稱以在 Swift 中對該表示進行任何操作,但在“包含結構數組的結構數組”版本中很清楚。 因此,在這種情況下,您只需將前面示例中獲取結果的調用替換為:

    let results = mainList.filter { $0.organisationName == "Pizza" }.map { $0.subList }.flatMap { $0 }
    print("\(results)")

在這種情況下, .filter僅用於 select 的MainListElement項目,其organizationName等於"Pizza" 這給出了MainListElement實例的集合,盡管在這種情況下只有一個。 .map然后將該集合的元素轉換為相應[SubListElement]的集合。 與前面的示例一樣,這給出了[[SubListElement]] ,因此最終的.flatMap變平為[SubListElement]

output 是

[{326359, NNN}, {320909, PPP}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM