Как организовать массив словарей на основе значения ключа внутри них? - PullRequest
0 голосов
/ 28 марта 2020

У меня есть массив информации, который хранится следующим образом:

(
            {
        actual = "<null>";
        code = "AUTO.US";
        date = "2019-12-31";
        difference = "<null>";
        estimate = "-0.12";
        percent = "<null>";
        "report_date" = "2020-03-27";
    },
            {
        actual = "<null>";
        code = "APTX.US";
        date = "2019-12-31";
        difference = "<null>";
        estimate = "-0.5600000000000001";
        percent = "<null>";
        "report_date" = "2020-03-30";
    },
{

        actual = "<null>";
        code = "BLAH.US";
        date = "2019-12-31";
        difference = "<null>";
        estimate = "-0.5600000000000001";
        percent = "<null>";
        "report_date" = "2020-03-30";
    }
);

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

(
        {
        "2020-03-27" =         (
                        {
                actual = "<null>";
                code = "AUTO.US";
                date = "2019-12-31";
                difference = "<null>";
                estimate = "-0.12";
                percent = "<null>";
                "report_date" = "2020-03-27";
            }
        );
    },
        {
        "2020-03-30" =         (
                        {
                actual = "<null>";
                code = "APTX.US";
                date = "2019-12-31";
                difference = "<null>";
                estimate = "-0.5600000000000001";
                percent = "<null>";
                "report_date" = "2020-03-30";
            },
        {

        actual = "<null>";
        code = "BLAH.US";
        date = "2019-12-31";
        difference = "<null>";
        estimate = "-0.5600000000000001";
        percent = "<null>";
        "report_date" = "2020-03-30";
    }
        );
    }
)

Для пояснения я хочу получить массив, содержащий словари с датой в качестве дня, которые содержат их в качестве объекта. массив исходных словарей с отчетной датой, соответствующей этому ключу. Таким образом, в массиве под ключом может быть несколько словарей заработка.

Я ценю любую помощь в этом!

Ответы [ 2 ]

0 голосов
/ 28 марта 2020

Вы никогда не должны использовать NSDictionary или NSArray в Swift, за исключением очень редких случаев. Вы должны использовать массивы и словари Swift. Также было бы полезно, если бы вы создали соответствующий struct для хранения ваших данных, а не использовали необработанные словари. Если ваши данные поступают из JSON, то вы можете просто использовать Codable для преобразования ваших данных.

Работая с тем, что у вас есть, вам необходимо преобразовать массив словарей [String:String] в словарь массивов [String:String], keyed by a [String] or the rather ugly [String: [[String: String]]] `:

Для этого просто переберите исходный массив, добавив каждый словарь в [String:[[String:String]]] dictionary:

func createEarningsDictionary(from earnings:[[String:String]] ) -> [String:[[String:String]]] {
    var arrayOfEarningsDicts = [String:[[String:String]]]()

    for earning in earnings {
        if let reportDate = earning["report_date"] {
            arrayOfEarningsDicts[reportDate, default:[[String:String]]()].append(earning)
    }
    return arrayOfEarningsDicts
}

Если бы вы использовали структуру Earnings вместо словаря [String:String], у вас было бы более читабельное:

func createEarningsDictionary(from earnings:[Earnings] ) -> [String:[Earnings]] {
    var earningsDict = [String:[Earnings]]()

    for earning in earnings {
        earningsDict[earning.reportDate, default:[Earnings]()].append(earning)
    }
    return earningsDict
}
0 голосов
/ 28 марта 2020

Вопрос немного вводит в заблуждение, но:

исходные данные уже являются массивом типа [[String: String]], а требуемый результат - массив типа [[String: [String: String]]].

следуйте следующему коду, чтобы попасть туда:

// building the original data
var dic1: [String: String] = [:]
dic1["actual"] = "<null>"
dic1["code"] = "AUTO.US"
dic1["date"] = "2019-12-31"
dic1["difference"] = "<null>"
dic1["estimate"] = "-0.12"
dic1["percent"] = "<null>"
dic1["report_date"] = "2020-03-27"

var dic2: [String: String] = [:]
dic2["actual"] = "<null>"
dic2["code"] = "APTX.US"
dic2["date"] = "2019-12-31"
dic2["difference"] = "<null>"
dic2["estimate"] = "-0.5600000000000001"
dic2["percent"] = "<null>"
dic2["report_date"] = "2020-03-30"

// the array of the original data
let array = [dic1, dic2]

// the interesting function
func sortThemOut() {
    var finalArray: [[String: [String: String]]] = []
    for dic in array {
        // get the `report_date` value from the original dictionary
        let reportDate = dic["report_date"] ?? "there was no value for the `report_date`"
        // create the new item that should be appended in the new array
        var newDic: [String: [String: String]] = [:]
        // set the key to the `reportDate`, and the value of that key to the original dictionary
        newDic[reportDate] = dic

        // append the new dictionary into the final array
        finalArray.append(newDic)
    }
    print(finalArray)
}

Тем не менее, я настоятельно рекомендую вам изменить это, чтобы вместо этого преобразовать исходные данные в словарь типа [String: [String: String]], который, как я полагаю, вам действительно нужен Намерение получить:

// the array of the original data
let array = [dic1, dic2]

func sortThemOut() {
    var finalDictionary: [String: [String: String]] = [:]
    for dic in array {
        // get the `report_date` value from the original dictionary
        let reportDate = dic["report_date"] ?? "there was no value for the `report_date`"
        // set the key to the `reportDate`, and the value of that key to the original dictionary
        finalDictionary[reportDate] = dic
    }
    print(finalDictionary)
}

, который вы можете использовать следующим образом:

    // key will represent the `report_date`, and the value will contain the rest of the object
    for (key, value) in finalDictionary {
        print("key: " + key)
        print("value: \(value)")

        // OUTPUT:

        // key: 2020-03-27
        // value: ["report_date": "2020-03-27", "estimate": "-0.12", "code": "AUTO.US", "difference": "<null>", "date": "2019-12-31", "actual": "<null>", "percent": "<null>"]

        // key: 2020-03-30
        // value: ["report_date": "2020-03-30", "estimate": "-0.5600000000000001", "date": "2019-12-31", "difference": "<null>", "percent": "<null>", "actual": "<null>", "code": "APTX.US"]
    }

    print(finalDictionary["2020-03-27"])
    // ["report_date": "2020-03-27", "estimate": "-0.12", "code": "AUTO.US", "difference": "<null>", "date": "2019-12-31", "actual": "<null>", "percent": "<null>"]

ОБНОВЛЕНИЕ

На основе пояснений в комментариях ниже, полученный объект будет работать быть словарем типа `[String: [[String: String]]] ', поэтому функция будет иметь вид:

func sortThemOut() {
    var finalDictionary: [String: [[String: String]]] = [:]
    for dic in array {
        // get the `report_date` value from the original dictionary
        let reportDate = dic["report_date"] ?? "there was no value for the `report_date`"
        // creating an array that will hold the original objects
        // try to get the array that was previously inserted (if a previous object with same report_date was inserted before, or assign an new empty array
        var objects = finalDictionary[reportDate] ?? []

        // append the object into the array
        objects.append(dic)

        // set the key to the `reportDate`, and the value of that key to the array of original objects
        finalDictionary[reportDate] = objects
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...