0

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.

user6631314
  • 1,751
  • 1
  • 13
  • 44
  • It might help if you provide your extension code. – nteissler Apr 02 '20 at 16:39
  • What @nteissler said. Also, why are you messing with NSArrays in Swift. There should be no reason for that. – Rob C Apr 02 '20 at 16:40
  • The reason for the NSArray is that most of the project is in Obj-C. However, what I want to do, create an an array of unique values sorted by incidence is easier in Swift. So I thought I would use a Swift extension. – user6631314 Apr 02 '20 at 16:53

1 Answers1

1

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

nteissler
  • 1,513
  • 15
  • 16