Необязательные параметры в словарных массивах

Я работаю над некоторым кодом и получил неверный вывод и пытался его решить, я знаю, что это довольно простое исправление (или, по крайней мере, должно быть), возможно, правильное его преобразование или обработка. Тем не менее, у меня было несколько попыток без успеха.

Вот код в Swift Playground

import UIKit
import Foundation

//  MARK:- Declarations

//  The varible defintions including the expected unique key values, the associated data and the dictionary which will be returned
var arrayOfUniqueFieldNames = ["value1", "value2", "value3"]
var dictionaryOfKeyPairedData : [Int: [String]] = [
    0: ["value1", "a"],
    1: ["value2", "b"],
    2: ["value3", "c"],
    3: ["value1", "x"],
    4: ["value2", "y"],
    5: ["value3", "z"]]
var dictionaryOfDatasets = [String: Any]()

// MARK:- Code Body

//  Iterates through the dictionaryOfKeyPairedData assigning each key if it doesn't exist to the array to print and the value to the existing key, each key has mutliple values stored as an array
for counterOne in 0...dictionaryOfKeyPairedData.count-1{
    
    //  gets the current key value from the dictionary as a String
    let currentKeyValue = returnKeyofDictionaryArray(theDictionaryInQuestion: dictionaryOfKeyPairedData, indexToLookUp: counterOne, value: 0)
    //  gets the current value from the dictionary as a String as it associates with the current key
    let currentValuePair = returnKeyofDictionaryArray(theDictionaryInQuestion: dictionaryOfKeyPairedData, indexToLookUp: counterOne, value: 1)
    //  Fetches the array from the dictionary so it can be manipulated
    var existingItems = Array(arrayLiteral: dictionaryOfDatasets[currentKeyValue]) //Where I believe the Optional is not handled correctly
    //  If the key doesn't exist it saves the value as the key to the key, if it does exist it saves the value to the value as a value
    if existingItems[0] == nil{
        existingItems = [currentValuePair] //Where I believe the extranious brackets are getting added
    }else{
        existingItems.append(currentValuePair)
    }
    //  resaves the manipulated array alongside the existing key
    dictionaryOfDatasets[currentKeyValue] = existingItems
}

//  prints the data - OUTPUT
print(dictionaryOfDatasets)


//  MARK:- Functions
//  Returns the key for the value for the prescribed array
func returnKeyofDictionaryArray(theDictionaryInQuestion: [Int: [String]], indexToLookUp: Int, value: Int) -> String{
    return theDictionaryInQuestion[indexToLookUp]![value]
}

Ожидаемый результат

["value2": ["b", "y"], "value1": ["a", "x"], "value3": ["c","z"]]

или

["value1": ["a", "x"], "value2": ["b", "y"], "value3": ["c","z"]]

Фактический результат

["value1": [Optional([Optional("a")]), Optional("x")], "value2": [Optional([Optional("b")]), Optional("y")], "value3": [Optional([Optional("c")]), Optional("z")]]

Почему ваши входные данные в таком формате, которым так неудобно манипулировать? Цифры в качестве ключей кажутся совершенно ненужными. Как насчет того, чтобы просто хранить строки в коллекции KeyValuePairs или, по крайней мере, [(String, String)]? Цифровые клавиши вообще что-нибудь означают?

Sweeper 22.03.2022 13:37

Поскольку есть дублирующиеся «ключи», необходима нумерация.

Yellow 22.03.2022 14:32

К вашему сведению, и KeyValuePairs, и [(String, String)] допускают дублирование ключей.

Sweeper 22.03.2022 14:34
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
3
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы используете Any в качестве типа значения выходного словаря, в то время как это может быть просто массив Strings. И использование Array(arrayLiteral: dictionaryOfDatasets[currentKeyValue]) не помогает.

Вы можете получить желаемый результат, перебирая исходный словарь и сохраняя значения непосредственно в новом, без вспомогательной функции, такой как returnKeyofDictionaryArray.

Вот как вы можете этого добиться:

        //  The variable defintions including the expected unique key values, the associated data and the dictionary which will be returned
        var arrayOfUniqueFieldNames = ["value1", "value2", "value3"]
        var dictionaryOfKeyPairedData : [Int: [String]] = [
            0: ["value1", "a"],
            1: ["value2", "b"],
            2: ["value3", "c"],
            3: ["value1", "x"],
            4: ["value2", "y"],
            5: ["value3", "z"]]
        
        // This is a dictionary of String to String-arrays
        var dictionaryOfDatasets = [String: [String]]()

        // MARK:- Code Body
        
        // Just iterate through the values of the dictionary, given that
        // you are not interested in the Int keys
        dictionaryOfKeyPairedData.values.forEach {
            if dictionaryOfDatasets[$0[0]] == nil {
                dictionaryOfDatasets[$0[0]] = [$0[1]]
            } else {
                dictionaryOfDatasets[$0[0]]?.append($0[1])
            }
        }
        
        // Sorting, if you need:
        // Here is where you sort the arrays inside each value of the dictionary
        dictionaryOfDatasets.keys.forEach {
            dictionaryOfDatasets[$0] = dictionaryOfDatasets[$0]?.sorted(by: { $0 < $1 })
        }

        //  prints the data - OUTPUT
        print(dictionaryOfDatasets)   // ["value3": ["c", "z"], "value2": ["b", "y"], "value1": ["a", "x"]]

Вы, сначала вам нужно изменить Dictioanry ключ Any на String И вы можете добиться ожидаемого результата более элегантным способом.

var arrayOfUniqueFieldNames = ["value1", "value2", "value3"]
var dictionaryOfKeyPairedData : [Int: [String]] = [
    0: ["value1", "a"],
    1: ["value2", "b"],
    2: ["value3", "c"],
    3: ["value1", "x"],
    4: ["value2", "y"],
    5: ["value3", "z"]]
var dictionaryOfDatasets = [String: [String]]()

arrayOfUniqueFieldNames.forEach{
    let key = $0
    dictionaryOfKeyPairedData.filter({$0.value.first == key}).forEach{
        if dictionaryOfDatasets[key] != nil {
            var val = dictionaryOfDatasets[key]
            val?.append($0.value.last ?? "")
            dictionaryOfDatasets[key] = val

        }else{
            dictionaryOfDatasets[key] = [$0.value.last ?? ""]

        }
    }
}
print(dictionaryOfDatasets)

OUTPUT:

["value1": ["a", "x"], "value3": ["z", "c"], "value2": ["y", "b"]]

Другие вопросы по теме