简体   繁体   中英

Swift: sort array of [Any] by item type

I have an array that contains objects of different types. In my actual code these are custom types that conform to the same protocol, but the principle also applies to the following code:

let anyObjectArray: [Any] = [51, "g", "hello", 1, 30111]

var sortedArray: [Any] = []

for item in anyObjectArray where item is Int {
    sortedArray.append(item)
}
for item in anyObjectArray where item is String {
    sortedArray.append(item)
}
print(sortedArray)

// 51, 1, 30111, "g", "hello"

As you can see I want to sort the array by item type.

I am wondering if iterating several times over the array is an appropriate approach. Is there a possibility using .map to sort an array by item type, and if so, would that be more efficient?

The arrays in my actual code would contain a maximum of 4-5 elements, sometimes only one, on the other hand there would be more different types than just two, so the number of for in loops will be higher (possibly 4-5)

This is almost certainly a horrible idea, and is almost certainly masking a major type-mistake, but not difficult to implement. You would sort by the types, just as you say. Since types aren't directly comparable, you can sort by their names.

anyObjectArray.sorted { "\(type(of: $0))" < "\(type(of: $1))" }

But this deeply feels like Array was the wrong type in the first place. It feels like you really want a dictionary here.

This will not sort the array but group the elements by type in a dictionary

var map = [String: [Any]]()

anyObjectArray.forEach( {
    let key = "\([type(of: $0))"
    if map[key] == nil { map[key] = [] }
    map[key]?.append($0)
})

Or alternatively for Swift 4.2 (or later) as suggested by Rob Napier

let map = Dictionary(grouping: anyObjectArray, by: { "\(type(of: $0))" })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM