Каков наилучший способ в Swift 4+ хранить набор однородных массивов для различных типов в словаре? - PullRequest
0 голосов
/ 20 ноября 2018

Рассмотрим ситуацию, когда мы хотим иметь словарь массивов, где каждый массив представляет собой однородную коллекцию значений некоторого типа (который может быть структурным или примитивным типом).В настоящее время я использую ObjectIdentifier типа, определяющего его таким образом:

let pInts : [UInt32] = [4, 6, 99, 1001, 2032]
let pFloats : [Float] = [3.14159, 8.9]
let pBools : [Bool] = [true, false, true]

let myDataStructure : [ObjectIdentifier : [Any]] = [
   ObjectIdentifier(Float.self) : pFloats,
   ObjectIdentifier(UInt32.self) : pInts,
   ObjectIdentifier(Bool.self) : pBools
]

Проблема здесь заключается в том, что при обходе структуры данных Swift не знает, что объекты в каждом списке являются однородными.Поскольку swift имеет статическую типизацию, я предполагаю, что невозможно типизировать списки [Any], используя ключи ObjectIdentifier.Рассмотрим этот псевдокод обхода:

for (typeObjId, listOfValuesOfSometype) in myDataStructure {
   // do something like swap values around in the array,
   // knowing they are homogeneously but anonymously typed
}

Итак, есть ли какой-нибудь механизм метатипа, который я могу придумать, чтобы представить эту структуру данных таким образом, чтобы он не предвосхищал список фактических типов, которые будут иметь массивы?

1 Ответ

0 голосов
/ 22 ноября 2018

Я не совсем уверен, чего вы хотите достичь. Внутри словарного цикла массивы всегда будут иметь тип Any, но если вы хотите перемещать элементы в массивах, вы можете просто сделать это.Просто переназначьте массив сначала на переменную, а затем поместите обратно в словарь.

Если вы хотите перебрать элементы определенного типа, вы можете использовать вспомогательную функцию массива ниже.

func testX() {
    let pInts: [UInt32] = [4, 6, 99, 1001, 2032]
    let pFloats: [Float] = [3.14159, 8.9]
    let pBools: [Bool] = [true, false, true]

    var myDataStructure: [ObjectIdentifier: [Any]] = [
        ObjectIdentifier(Float.self): pFloats,
        ObjectIdentifier(UInt32.self): pInts,
        ObjectIdentifier(Bool.self): pBools
    ]

    // Swap the first 2 items of every array
    for d in myDataStructure {
        var i = d.value
        if i.count > 1 {
            let s = i[0]
            i[0] = i[1]
            i[1] = s
        }
        myDataStructure[d.key] = i
    }

    // Now dump all data per specific type using the array helper function.
    for i: UInt32 in array(myDataStructure) {
        print(i)
    }
    for i: Float in array(myDataStructure) {
        print(i)
    }
    for i: Bool in array(myDataStructure) {
        print(i)
    }
}

func array<T>(_ data: [ObjectIdentifier: [Any]]) -> [T] {
    return data[ObjectIdentifier(T.self)] as? [T] ?? []
}
...