简体   繁体   English

嵌套的结构数组中的Swift匹配元素

[英]Swift matching elements within nested array of structs

I'm a Swift newbie and I'm trying to get to grips with the following data structure. 我是一个Swift新手,我正试图掌握以下数据结构。 I have an array ( categories ) of category structs. 我有一个category结构的数组( categories )。 Each category struct contains an array of business structs stored as a value on the property items . 每个category结构包含一个business结构数组,存储为属性items的值。 I'm not sure how to represent this kind of thing but hopefully this pseudo-code makes it a little bit clearer: 我不确定如何表示这种事情,但希望这个伪代码使它更清晰一些:

categories: [category]
   - category: Struct
        .categoryId: Int
        .items: [business]
            - business: Struct
               .busId: Int
            - business: Struct
               .busId: Int
   - category: Struct
        .categoryId: Int
        .items: [business]
            - business: Struct
               .busId: Int
            - business: Struct
               .busId: Int

Given a busId I'm trying to return a matching business Struct and the categoryId in which it is contained. 给定一个busId我试图返回一个匹配的business Struct和包含它的categoryId I've tried using FlatMap and Map but I'm going round in circles trying to unwrap and filter this data structure. 我已经尝试过使用FlatMap和Map,但是我想绕圈试图解开并过滤这个数据结构。

Any pointers/advice about approaches to take would be great. 有关采取方法的任何指示/建议都会很棒。

Given a Business struct defined like this 给定一个像这样定义的Business结构

struct Business {
    let busID: Int
}

A Category like this 像这样的类别

struct Category {
    let categoryID: Int
    let business: [Business]
}

And a list of Category 并列出了类别

let categories = [
    Category(categoryID: 0, business: [Business(busID:0)]),
    Category(categoryID: 1, business: [Business(busID:1), Business(busID:2)])
]

We can extract the categoryID and the Business having a given Int 我们可以提取categoryID和具有给定Int的Business

func search(businessID: Int, categories: [Category]) -> (categoryID: Int, business:Business)? {
    let res = categories.reduce([Int:Business]()) { (res, category) ->  [Int:Business] in
        guard res.isEmpty else { return res }
        var res = res
        if let business = (category.business.filter { $0.busID == businessID }).first {
            res[category.categoryID] = business
        }
        return res
    }

    guard let categoryID = res.keys.first, business = res[categoryID] else  { return nil }
    return (categoryID, business)
}

Example

在此输入图像描述

Update 更新

This is a shorter version which does not use reduce 这是一个不使用reduce的较短版本

func search(businessID: Int, categories: [Category]) -> (categoryID: Int, business:Business)? {
    guard let
        category = (categories.filter { $0.business.contains { $0.busID == businessID } } ).first,
        business = (category.business.filter { $0.busID == businessID } ).first
    else { return nil }
    return (category.categoryID, business)
}

How's this? 这个怎么样?

categories.filter{category in //filter the categories as the final result
    category.items //get the Businesses in the category
            .map{$0.busId} //get the busIds of the Businesses
            .contains(desiredBusinessID) //keep iff the desired busId is present
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM