Swift - поиск дубликатов данных Json и слияние

Я использую swiftyjson, чтобы возиться с моими данными json.

В настоящее время я получаю данные, значения которых я хочу объединить. (это станет более понятным, если вы посмотрите на пример ниже. Я пробовал много разных подходов, таких как использование цикла for для просмотра данных JSON, но он все дублирует. Я также попытался изменить свой json на 2d массив, затем фильтруя его, но похоже, что это все усложняет. Должен быть более простой способ ...

var jsondata = {
{
    fruit: "APPLE"
    amount: 10
},{
    fruit: "Mango"
    amount: 5 
},{
    fruit: "APPLE"
    amount: 5 
},{
    fruit: "Mango"
    amount: 5 
},{
    fruit: "orange"
    amount: 500
}
}


var NEWjsondata = 
{
    {
    fruit: "APPLE"
    amount: 15
    },
    {
    fruit: "Mango"
    amount: 10
    },
    {
    fruit: "orange"
    amount: 500
    }
}

Мой подход

var arr = ["Apple","Mango","Orange"]
for (key,json) in jsondata {
arr.append(json["fruit"])
if arr.contains(json["fruit"]){
json["amount"] = json["amount"] + json["amount"]
}}

Это недействительные данные JSON. Здесь вы можете увидеть, действителен ли он.

Fabian 24.07.2018 16:37

@ Цель, это помощник в псевдокоде:]

iloveStackOverflow 24.07.2018 16:45

покажите код, который вы пробовали. создать новый словарь, который может поддерживать тип элемента в массиве, а затем выполнить итерацию по массиву, если «фрукт» уже есть, добавить сумму, если не добавить фрукт и количество.

Scriptable 24.07.2018 16:51

@Scriptable обновил пост с моим подходом. Проблема с вашим предложением заключается в том, что это приведет к добавлению повторяющихся записей. Это был первый подход, который я применил.

iloveStackOverflow 24.07.2018 16:57

нет, если вы сначала проверите наличие плодов.

Scriptable 24.07.2018 16:58

@Scriptable Я. Я добавляю переменную arr по мере того, как я просматриваю файл json в цикле for. Взгляните на мое обновление. Я проверяю, содержит ли уже следующий фрукт

iloveStackOverflow 24.07.2018 17:08
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
6
118
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я просматриваю все словари и извлекаю из каждого фрукта название и количество, а затем делаю новую запись в словаре результатов или добавляю к уже подсчитанному ранее количеству.

func mergedDict(dictionaries: [[String: Any]]) -> [String: Int] {
    guard dictionaries.count != 0 else { return [:] }

    var result = [String: Int]()

    dictionaries.forEach { dict in
        var name: String?
        var amount: Int?
        dict.forEach{ arg in
            switch arg.key {
            case "fruit":
                name = arg.value as! String
            case "amount":
                amount = arg.value as! Int
            default:
                fatalError("does not exist.")
            }
        }

        guard let fruit = name else { fatalError("name is nil.") }
        guard let newAmount = amount else { fatalError("amount is nil.") }

        guard let priorAmount = result[fruit] else {
            result[fruit] = newAmount
            return
        }
        result[fruit] = priorAmount + newAmount
    }

    return result
}

Приведение FruitStruct в соответствие с протоколом Codable позволяет encoder.encode принимать наш массив FruitStruct. Структура имитирует JSON, который мы хотим. Можно добавить enum CodingKeys, чтобы изменить отображение структуры на фактический JSON.

struct FruitStruct: Codable {
    let fruit: String
    let amount: Int
}

func json(fromDict: [String: Int]) throws -> String {
    let fruitStructs = fromDict.map { arg in
        return FruitStruct(fruit: arg.key, amount: arg.value)
    }

    let encoder = JSONEncoder()
    encoder.outputFormatting = .prettyPrinted

    let data = try encoder.encode(fruitStructs)

    guard let string = String(data: data, encoding: .utf8) else {
        fatalError("failed to decode json-Data to String with utf8.")
    }
    return string
}

@iloveStackOverflow. Вы можете создать struct FruitStruct { let fruit: String; let amount: Int}, сопоставить mergedDict с [FruitStruct] и закодировать его с помощью JSONEncoder. Сможете ли вы это сделать или вам нужно больше рекомендаций?

Fabian 24.07.2018 18:35

Кстати ... в JSONEncoder есть параметр .prettyPrint.

Fabian 24.07.2018 18:40

Ничего, я разберусь. Еще раз, спасибо :]

iloveStackOverflow 24.07.2018 19:19

на самом деле да, мне нужно больше рекомендаций относительно структуры фруктов. Пытался сам, но не могу заставить его работать.

iloveStackOverflow 24.07.2018 20:06

@iloveStackOverflow Для этого вы должны прочитать о Encodable, CodingKeys и функции карты. Вы должны знать .filter, .map, .sorted, .enumerated, .forEach наизусть, так что читайте и о них. Они делают жизнь намного проще. Map использует универсальные шаблоны, чтобы попытаться определить тип вывода. Обновил пост.

Fabian 24.07.2018 20:19

Нормально будет сделать. И я предполагаю, что "toJson" должен принимать параметр [[String: Int]], а не [String: Int], поскольку я буду передавать в него результат возврата от mergeDict.

iloveStackOverflow 24.07.2018 20:31

@iloveStackOverflow Я думаю, что у вас все не так, но да, вывод mergedDict переходит в toJSON. Не забывай заглядывать в темы, а то мне будет грустно. ;)

Fabian 24.07.2018 20:36

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