Ios 过滤一组数据模型

Ios 过滤一组数据模型,ios,swift,sorting,data-structures,enums,Ios,Swift,Sorting,Data Structures,Enums,我有一个数据模型,其中包括一个结构数组。我用它来填充一个tableView。很好,但是我需要帮助过滤数据 我希望能够通过extremeSport枚举进行过滤(通过按下UI中的一个按钮)。在下面的示例中,有3项运动包含8个技巧。最终,将有大约10项运动和150-200个技巧(可能还有更多技巧)。过滤在这里是有意义的 问题是我不知道如何从节到极值模型,这样我就可以通过极值端口进行过滤。我得到的最接近的是按部门名称字母排序 struct ExtremeModel { let trick: St

我有一个数据模型,其中包括一个结构数组。我用它来填充一个tableView。很好,但是我需要帮助过滤数据

我希望能够通过extremeSport枚举进行过滤(通过按下UI中的一个按钮)。在下面的示例中,有3项运动包含8个技巧。最终,将有大约10项运动和150-200个技巧(可能还有更多技巧)。过滤在这里是有意义的

问题是我不知道如何从节到极值模型,这样我就可以通过极值端口进行过滤。我得到的最接近的是按部门名称字母排序

struct ExtremeModel {
    let trick: String
    let definition: String
    let extremeSport: Sport
    enum Sport {
        case bmx
        case skateboarding
        case snowboarding
    }
}
struct Sections {
    let sectionName: String
    let Objects: [ExtremeModel]
}

struct Data {
    static func allTricks() -> [Sections] {
        return [
            Sections(sectionName: "A", Objects: [
                ExtremeModel(trick: "Acid Drop", definition: "Lorem ipsum", extremeSport: .skateboarding),
                ExtremeModel(trick: "Axel Stall", definition: "Lorem ipsum", extremeSport: .skateboarding)
            ]),
            Sections(sectionName: "B", Objects: [
                ExtremeModel(trick: "Back Flip", definition: "Lorem ipsum", extremeSport: .snowboarding),
                ExtremeModel(trick: "Bar Spin", definition: "Lorem ipsum", extremeSport: .bmx),
                ExtremeModel(trick: "Bunny Hop", definition: "Lorem ipsum", extremeSport: .bmx)
            ]),
            Sections(sectionName: "S", Objects: [
                ExtremeModel(trick: "Shifty", definition: "Lorem ipsum", extremeSport: .snowboarding),
                ExtremeModel(trick: "Shuvit", definition: "Lorem ipsum", extremeSport: .skateboarding),
                ExtremeModel(trick: "Stalefish", definition: "Lorem ipsum", extremeSport: .snowboarding)
            ]),
        ]
    }
}
用法。这就是我在做这类事情时遇到困难的地方

let allTerms = Data.allTricks()

// Here, I am filtering by Section Name. I want to filter by extremeSport, so I can update the view based on sports.
let filteredSports = allTerms.filter { (sport:Sections) -> Bool in
    return sport.sectionName == "A"
}

如何按极值端口枚举筛选allTricks()数据?前面几点:

  • 正如@Alexander提到的,您应该考虑构建数据的最佳方式。我的答案涉及到对代码的最小更改量。。。想想这是否合适
  • 按照惯例,结构名称是单数的
我想这就是你想要做的:

struct ExtremeModel {
    var trick: String!
    var definition: String!
    var extremeSport: Sport!
    enum Sport {
        case bmx
        case skateboarding
        case snowboarding
    }
}

// Struct names should be singular!
struct Section {
    var sectionName: String!
    var Objects: [ExtremeModel]!
}

// Renamed to avoid collision with Foundation's Data class
struct MyData {
    static func allTricks() -> [Section] {
        return [
            Section(sectionName: "A", Objects: [
                ExtremeModel(trick: "Acid Drop", definition: "Lorem ipsum", extremeSport: .skateboarding),
                ExtremeModel(trick: "Axel Stall", definition: "Lorem ipsum", extremeSport: .skateboarding)
                ]),
            Section(sectionName: "B", Objects: [
                ExtremeModel(trick: "Back Flip", definition: "Lorem ipsum", extremeSport: .snowboarding),
                ExtremeModel(trick: "Bar Spin", definition: "Lorem ipsum", extremeSport: .bmx),
                ExtremeModel(trick: "Bunny Hop", definition: "Lorem ipsum", extremeSport: .bmx)
                ]),
            Section(sectionName: "S", Objects: [
                ExtremeModel(trick: "Shifty", definition: "Lorem ipsum", extremeSport: .snowboarding),
                ExtremeModel(trick: "Shuvit", definition: "Lorem ipsum", extremeSport: .skateboarding),
                ExtremeModel(trick: "Stalefish", definition: "Lorem ipsum", extremeSport: .snowboarding)
                ]),
        ]
    }
}

let allTricks = MyData.allTricks()

let filteredSports = allTricks.filter { (section) -> Bool in
    return section.Objects.contains(where: { (extremeModel) -> Bool in
        return extremeModel.extremeSport == .skateboarding
    })
}

print(filteredSports.count)

我会稍微修改一下你的模型。我建议你使用
字典
,而不是
数组
,这样你就可以更自然地找到你感兴趣的技巧

enum ExtremeSport {
    case bmx
    case skateboarding
    case snowboarding
}

struct ExtremeSportTrick {
    let name: String
    let definition: String
    let extremeSport: ExtremeSport
}


struct SportData {
    static let allTricks = [
        ExtremeSportTrick(name: "Acid Drop", definition: "Lorem ipsum", extremeSport: .skateboarding),
        ExtremeSportTrick(name: "Axel Stall", definition: "Lorem ipsum", extremeSport: .skateboarding),
        ExtremeSportTrick(name: "Back Flip", definition: "Lorem ipsum", extremeSport: .snowboarding),
        ExtremeSportTrick(name: "Bar Spin", definition: "Lorem ipsum", extremeSport: .bmx),
        ExtremeSportTrick(name: "Bunny Hop", definition: "Lorem ipsum", extremeSport: .bmx),
        ExtremeSportTrick(name: "Shifty", definition: "Lorem ipsum", extremeSport: .snowboarding),
        ExtremeSportTrick(name: "Shuvit", definition: "Lorem ipsum", extremeSport: .skateboarding),
        ExtremeSportTrick(name: "Stalefish", definition: "Lorem ipsum", extremeSport: .snowboarding)
    ]

    static func allTricksByFirstLetter() -> [String: [ExtremeSportTrick]] {
        return Dictionary(grouping: allTricks, by: { String($0.name.first!) })
    }

    static func allTricksBySport() -> [ExtremeSport: [ExtremeSportTrick]] {
        return Dictionary(grouping: allTricks, by: { $0.extremeSport })
    }
}
用法示例:

extension Dictionary {
    func prettyString<T>() -> String where Dictionary.Value == [T] {
        return Array(self)
            .map{ key, values in """
            \(key): [
                \(values.map{ "\($0)" }.joined(separator: ",\n\t"))
            ]
            """ }
            .joined(separator: ",\n")
    }
}

let allTricksBySport = SportData.allTricksBySport()
let allTricksByFirstLetter = SportData.allTricksByFirstLetter()
let allBMXTricks = allTricksBySport[.bmx]
let allATricks = SportData.allTricksByFirstLetter()["A"]

print("=== All tricks by sport:")
print(allTricksBySport.prettyString())
print("\n\n\n=== All tricks by first letter:")
print(allTricksByFirstLetter.prettyString())
print("\n\n\n=== All bmx tricks:")
print(allBMXTricks!.map{ "\($0)"}.joined(separator: ",\n"))
print("\n\n\n=== All tricks whose name starts with \"A\":")
print(allATricks!.map{ "\($0)"}.joined(separator: ",\n"))

根据您对可更改性的需求,这些数组有多大/贵等,您可能想使用<代码>懒var 实现<代码> AutoTraceBysFrase< /Cl>和<代码> AutoTracsBysOp> <代码> .< /P>我将使用一个不同的结构名称而不是<代码>数据< /代码>,因为有一个基础类叫做“代码>数据< /代码>伟大的调用!我已将其重命名为SportData:)所有这些

var
s和隐式展开的选项。。。哎呀@亚历山大-谢谢你指出这一点!我一直在做错事。哎呀!我编辑了我的帖子:)在allTricksBySport函数中,我得到:无法将类型为“Dictionary”的返回表达式转换为返回类型“[ExtremeSport:[ExtremeSportTrick]]”@Joe Oops,我犯了一个复制/粘贴错误。看我的编辑这太棒了!通过简化我的数据,并提供多种排序方法,您超越了我的能力。谢谢大家!@乔:)
字典(分组:by:)
非常好,再问一个简单的问题!您现在给了我按季节对运动进行排序的想法:)我尝试了以下方法:让allSummerSports=allTricksBySport[.skateboarding,.bmx]-但是它给了我“缺少参数标签”默认值:“在下标中”感谢您的帮助,并为我提供了一些有用的“最佳实践”提示。这些会派上用场的!:)@乔:没问题!我有两个项目,一个在你的帮助下,另一个在alexanders的帮助下。关于你的解决方案-过滤似乎是过滤包含极限运动的部分(而不是部分和术语)。例如,如果我过滤.bmx,我将从B部分获得所有术语(因为B部分是唯一有bmx的部分)。是否有一种方法可以过滤节和术语以仅显示运动?是否希望数组包含
s或
极值模型
s?两个极值模型都按节组织。我只想过滤掉所有不合适的结果。例如,如果我过滤.bmx,我将有一个带旋转和兔子跳的B部分。另一个例子-如果我过滤.skateboarding,我将有Shuvit的A部分(两个技巧)和S部分。
=== All tricks by sport:
snowboarding: [
    ExtremeSportTrick(name: "Back Flip", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding),
    ExtremeSportTrick(name: "Shifty", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding),
    ExtremeSportTrick(name: "Stalefish", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding)
],
bmx: [
    ExtremeSportTrick(name: "Bar Spin", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx),
    ExtremeSportTrick(name: "Bunny Hop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx)
],
skateboarding: [
    ExtremeSportTrick(name: "Acid Drop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
    ExtremeSportTrick(name: "Axel Stall", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
    ExtremeSportTrick(name: "Shuvit", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding)
]



=== All tricks by first letter:
B: [
    ExtremeSportTrick(name: "Back Flip", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding),
    ExtremeSportTrick(name: "Bar Spin", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx),
    ExtremeSportTrick(name: "Bunny Hop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx)
],
A: [
    ExtremeSportTrick(name: "Acid Drop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
    ExtremeSportTrick(name: "Axel Stall", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding)
],
S: [
    ExtremeSportTrick(name: "Shifty", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding),
    ExtremeSportTrick(name: "Shuvit", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
    ExtremeSportTrick(name: "Stalefish", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.snowboarding)
]



=== All bmx tricks:
ExtremeSportTrick(name: "Bar Spin", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx),
ExtremeSportTrick(name: "Bunny Hop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.bmx)



=== All tricks whose name starts with "A":
ExtremeSportTrick(name: "Acid Drop", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding),
ExtremeSportTrick(name: "Axel Stall", definition: "Lorem ipsum", extremeSport: Untitled.ExtremeSport.skateboarding)