【问题标题】:array filtering based on multiple enum selected conditions in swiftswift中基于多个枚举选择条件的数组过滤
【发布时间】:2022-01-19 16:05:59
【问题描述】:

在我的应用程序中点击过滤器按钮时,我会在过滤器下方显示给用户。

我有结构数组 - 站点,我需要根据用户选择的枚举过滤数组。

它涉及 AND 和 OR 条件。如果用户只选择underconstruction然后过滤数组,如果用户同时选择underconstruction和fullconstruction然后过滤数组。同样的情况也适用于 Size。

下面是代码:

 struct Site {
    var name :String = ""
    var sitestate: [State] = []
    var sitesize:[Size] = []
    var city :String = ""
    var country :String = ""
}

enum State : Int, CaseIterable {
        case underConstruction = 0
        case fullyConstructed
}

enum Size : Int, CaseIterable {
        case small = 0
        case big
}

var sites: [Site]?

var a = Site(name: "Mumbai", sitestate: State.fullyConstructed, sitesize: Size.big, city: "Mumbai", country: "India")
var b = Site(name: "Delhi", sitestate: State.underConstruction, sitesize: Size.small, city: "Delhi", country: "India")

sites.append(a)
sites.append(b)

现在网站有 2 个元素。

/// this is works only for single enum selected
let filteredsite = self.sites?.filter {
        $0.underConstruction == State.underConstruction.rawValue
}

将用户选择的状态和大小存储在两个变量中。

var selectedState :[State] = []
var selectedSize :[Size] = []

我需要使用这些 selectedState 和 selectedSize 来过滤数组。

我试过...单个过滤器有效,但不确定如何使用过滤器组合,同时选择两个枚举的情况 - 如何应用过滤器??

【问题讨论】:

  • 您的代码很难理解,在您的示例中,您过滤了一个不存在的属性,并且 Site 实例可以有多个状态和大小值。例如,一个网站如何既小又大?请澄清您对 AND 和 OR 过滤的含义
  • @JoakimDanielson - 在站点数组中添加了 2 个元素,1 个元素的大小为大,其他元素的大小为 - 小。当我们需要使用用户选择的两个枚举过滤数组时 - 它应该显示 - 数组中的两个元素。
  • 您添加的代码不会编译,请确保Site 的定义是正确的,因为它在我看来不是这样。而且您还没有真正解释 AND/OR 逻辑。
  • @sia 请检查我的更新答案。
  • 它仍然无法编译。只需将其复制/粘贴到 Playground 中,您就会看到。 var sitestate: [State] = []var sitestate: [State] = [] Site 可以同时是 .underConstruction. fullyConstructed 吗? sitesize 也有同样的问题。为什么要排列?您使用的init() 方法建议相反,哪个正确?

标签: ios arrays swift filter


【解决方案1】:

我刚刚找到了一个可能的解决方案。结构会像

struct Site {
    var name = ""
    var sitestate: State = .underConstruction
    var sitesize: Size = .small
    var city = ""
    var country = ""
}

enum State : Int, CaseIterable {
       case underConstruction = 0
       case fullyConstructed
}

enum Size : Int, CaseIterable {
       case small = 0
       case big
}

像这样初始化sites对象

var sites: [Site] = []

然后你就可以用这个了

 let a = Site(name: "Mumbai", sitestate: State.fullyConstructed, sitesize: Size.big, city: "Mumbai", country: "India")
 let b = Site(name: "Delhi", sitestate: State.underConstruction, sitesize: Size.small, city: "Delhi", country: "India")

 sites.append(a)
 sites.append(b)
    
 let selectedState :[State] = [State.underConstruction]
 let selectedSize :[Size] = [Size.small]
    
  /// this is works only for single enum selected
 let filteredsite = self.sites.filter {
      selectedState.contains($0.sitestate) && selectedSize.contains($0.sitesize)
  }
  print(filteredsite.count) // 1

希望这应该可行。

【讨论】:

  • 此代码无法编译,您仅在过滤时使用硬编码值。
  • @JoakimDanielson 希望更新后的代码能够正常工作。
  • 它现在可以编译,但您可能应该检查问题的更新以及它的 cmets。
  • @JoakimDanielson 感谢您的建议。请您查看更新后的答案吗?
  • @FaysalAhmed Swift 是一种类型推断语言,Size.small 是多余的。 let selectedSize: [Size] = [.small]。这同样适用于初始化器Site(name: "Mumbai", sitestate: .fullyConstructed, sitesize: .big, city: "Mumbai", country: "India")
猜你喜欢
  • 1970-01-01
  • 2019-10-28
  • 2022-12-25
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 2019-09-10
  • 2022-07-21
  • 2021-11-21
相关资源
最近更新 更多