【问题标题】:Swift Set to ArraySwift 设置为数组
【发布时间】:2015-05-16 18:55:52
【问题描述】:

可以使用set.allObjects()NSSet 转换为Array,但在新的Set(Swift 1.2 中引入)中没有这种方法。仍然可以通过将 Swift Set 转换为 NSSet 并使用 allObjects() 方法来完成,但这不是最佳选择。

【问题讨论】:

    标签: arrays swift set


    【解决方案1】:

    您可以使用给定 Swift 中的所有元素创建一个数组 Set 干脆用

    let array = Array(someSet)
    

    这是可行的,因为Set 符合SequenceType 协议 Array 可以用序列初始化。示例:

    let mySet = Set(["a", "b", "a"])  // Set<String>
    let myArray = Array(mySet)        // Array<String>
    print(myArray) // [b, a]
    

    【讨论】:

    • 附带说明,let array = Array(someSet) 也适用于 Swift 2
    • ... 或者让 myArray = myNSSet.allObjects 为! [mySpecificType]
    • @plusangel:是的,如果给出了NSSet。问题是关于 Swift Set
    • @KendallHelmstetterGelner:我已经用 Swift 2.3 和 Swift 3 仔细检查了上面的代码示例。它按我预期的方式编译和工作。你得到什么错误?
    • @MartinR 有趣的是,我正在尝试使用来自 NSManagedObject 关系的集合,但当时它不喜欢 Array 构造函数 - 现在我尝试重现该问题,但我不能。我确实必须将“arrayLiteral:”标签添加到 Array 构造函数中。我删除了我之前的评论,所以它不会混淆任何人,感谢您的检查!不知道为什么Swift指南没有这个转换形式...
    【解决方案2】:

    在最简单的情况下,在 Swift 3 中,您可以使用 Arrayinit(_:) 初始化程序从 Set 获取 Arrayinit(_:) 有以下声明:

    init<S>(_ s: S) where S : Sequence, Element == S.Iterator.Element
    

    创建一个包含序列元素的数组。

    用法:

    let stringSet = Set(arrayLiteral: "car", "boat", "car", "bike", "toy")    
    let stringArray = Array(stringSet)
    
    print(stringArray)
    // may print ["toy", "car", "bike", "boat"]
    

    然而,如果你还想对Set的每个元素执行一些操作,同时将其转换为Array,你可以使用mapflatMap、@987654333 @、filterCollection协议提供的功能方法:

    let stringSet = Set(["car", "boat", "bike", "toy"])
    let stringArray = stringSet.sorted()
    
    print(stringArray)
    // will print ["bike", "boat", "car", "toy"]
    
    let stringSet = Set(arrayLiteral: "car", "boat", "car", "bike", "toy") 
    let stringArray = stringSet.filter { $0.characters.first != "b" }
    
    print(stringArray)
    // may print ["car", "toy"]
    
    let intSet = Set([1, 3, 5, 2]) 
    let stringArray = intSet.flatMap { String($0) }
    
    print(stringArray)
    // may print ["5", "2", "3", "1"]
    
    let intSet = Set([1, 3, 5, 2])
    // alternative to `let intArray = Array(intSet)`
    let intArray = intSet.map { $0 }
    
    print(intArray)
    // may print [5, 2, 3, 1]
    

    【讨论】:

    • 使用其中一种方法,我可以从可选集合中创建可选数组。
    【解决方案3】:

    我创建了一个简单的扩展,它为您提供了一个未排序的 Array 作为 Swift 4.0Set 的属性。

    extension Set {
        var array: [Element] {
            return Array(self)
        }
    }
    

    如果你想要一个排序数组,你可以添加一个额外的计算属性,或者修改现有的来满足你的需要。

    要使用它,只需调用

    let array = set.array
    

    【讨论】:

    • 如果扩展在框架中,需要添加public关键字
    【解决方案4】:

    补充:

    Swift 没有 DEFINED ORDER 用于 Set 和 Dictionary。因此,您应该使用 sorted() 方法来防止出现意外结果,例如您的数组可以像 ["a","b "] 或 ["b","a"] 而你不想要这个。

    解决这个问题:

    套装

    var example:Set = ["a","b","c"]
    let makeExampleArray = [example.sorted()]
    makeExampleArray 
    

    结果:["a","b","c"]

    没有 sorted()

    可以是:

    ["a","b","c"] or ["b","c","a",] or ["c","a","b"] or ["a","c","b"] or ["b","a","c"] or ["c","b","a"] 
    

    简单的数学:3! = 6

    【讨论】:

      【解决方案5】:

      对于 Swift 2.x 及更高版本(来自 Swift Programming Language guide on Collection Types)的当前答案似乎是像这样遍历 Set 条目:

      for item in myItemSet {
         ...
      }
      

      或者,使用“排序”方法:

      let itemsArray = myItemSet.sorted()
      

      似乎 Swift 设计者不喜欢将 allObjects 作为一种访问机制,因为 Set 并没有真正排序,所以他们想确保在没有应用显式排序的情况下不会得到一个数组。

      如果你不想要排序的开销并且不关心顺序,我通常使用 map 或 flatMap 方法,它们提取数组应该更快一些:

      let itemsArray = myItemSet.map { $0 }
      

      如果您需要它是特定类型的数组(例如,未声明为类型集的托管对象关系集的权利),这将构建一个 Set 持有的类型的数组,您可以这样做类似:

      var itemsArray : [MyObjectType] = []
      if let typedSet = myItemSet as? Set<MyObjectType> {
       itemsArray = typedSet.map { $0 }
      }
      

      【讨论】:

      • myItemSet.sorted() 要求元素为Comparable。 – myItemSet.map { $0 } 应该产生与Array(myItemSet) 相同的结果,两者都通过枚举集合的所有元素来创建一个数组。后者仍然适用于我,您的上述评论的一些细节将不胜感激。
      【解决方案6】:

      调用这个方法并传递你的集合

      func getArrayFromSet(set:NSSet)-> NSArray {
      
      return set.map ({ String($0) })
      }
      

      像这样:

      var letters:Set = Set<String>(arrayLiteral: "test","test") // your set
      print(self.getArrayFromSet(letters))
      

      【讨论】:

      • 使用 Array() 是更好的选择
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多