I am trying to make a Swift extension for NSArray that uses some Swift methods but am having trouble with the firsts step of creating a properly formatted Swift Array from the NSArray.
The incoming NSArray looks like
[@"Hello",@"Me",@"That",@"Me",@"Hello",@"Me",@"as",@"the"]
Here are different versions of the extension:
This version creates a valid array but because the array is an NSArray, not an array, fails on the line counts[item] with error
cannot subscript a value of type '[String : Int]' with an index of type 'Any'
public extension NSArray {
public var sortedArray: NSArray {
let array : NSArray = self
for item in array {
counts[item] = (counts[item] ?? 0) + 1
}
print("counts",counts)
The next one works but is not taking the array as an input
public extension NSArray {
public var sortedArray: NSArray {
var array = ["Hello","Me","That","Me","Hello","Me","as","the"]
for item in array {
counts[item] = (counts[item] ?? 0) + 1
}
print("counts",counts)
The following two methods compile but array2 and array3 end up being empty
public extension NSArray {
public var sortedArray: NSArray {
var array2: [String] = self.flatMap { $0 as? String } //This compiles but array is empty
var array3: [String] = self.compactMap({ $0 as? String }) //This compiles but
for item in array2 {
counts[item] = (counts[item] ?? 0) + 1
}
print("counts",counts)//prints 0 as the array is empty
Note: when I insert a breakpoint at beginning of extension, self is a valid NSArray with lots of elements.
Thanks for any suggestions.
It's worth noting that NSArray
bridging has become very good in recent versions of swift. For example, all of the below works
let array: NSArray = NSArray(array: [3, 2, 1])
print(array)
print(type(of: array))
let newArray = array.compactMap { $0 as? Int }.compactMap(UInt8.init)
print(newArray)
print(array.sorted(by: { (left, right) -> Bool in
guard let left = left as? Int, let right = right as? Int else {
return false
}
return left < right
}))
I think NSArray
gets compactMap
and friends from conformace to the Sequence
protocol. So the standard library is doing all it can to help you out here. Like @Rob mentioned, it's probably better to work with the bridging and not try to stay in NSArray
-land