Словарь, имеющий несколько словарей, соответствующих одному ключу Swift - PullRequest
0 голосов
/ 12 ноября 2018

В моей базе данных есть данные в следующем формате (не менее 100 000 из этих блоков данных):

{
  "ax" : 1.232,
  "ay" : 1.897,
  "az" : -0.232
  "timestamp" : 151232326789
 }

, который я получаю в своем приложении iOS в формате словаря и анализирую модель класса. Приведенные выше данные получены от датчика MPU6050, связывающегося с базой данных usgin NodeMCU. Поскольку NodeMCU не имеет собственных часов, единственной возможностью было присвоить метку времени данным, используя ServerValue.Timestamp. Таким образом, я не смог правильно структурировать свои данные JSON, которые мне теперь нужно отформатировать в приложении iOS.

Я извлекаю time и date из отметки времени в моей базе данных

Это формат, который мне нужен в моем интерфейсе:

{
  Date1 : {
          Time1 :{ 
                "ax" : 1.232,
                "ay" : 1.897,
                "az" : -0.232
                  },
          Time2 :{ 
                "ax" : 1.232,
                "ay" : 1.897,
                "az" : -0.232
                  },
          Time3 :{ 
                "ax" : 1.232,
                "ay" : 1.897,
                "az" : -0.232
                  },
          Time4 :{ 
                "ax" : 1.232,
                "ay" : 1.897,
                "az" : -0.232
                  }
            }
  Date2 : {...similar as above.}
   }

Я пытался использовать NSMutableDictionary, но данные путаются. Любое решение?

Ответы [ 4 ]

0 голосов
/ 12 ноября 2018
import Foundation

// define date - time interval for testing
let start = Calendar.current.date(from: DateComponents(year: 2018, month: 1, day: 1))
let end = Calendar.current.date(from: DateComponents(year: 2018, month: 1, day: 3))
let s = start!.timeIntervalSinceReferenceDate
let e = end!.timeIntervalSinceReferenceDate

// generate array of random data with timestamp from defined date - time interval
var data: [[String: Double]] = []
(0..<10).forEach { _ in
    let ax = Double.random(in: -1.0...1.0)
    let ay = Double.random(in: -1.0...1.0)
    let az = Double.random(in: -1.0...1.0)
    // stamp between start and end date, with one second resolution
    let timestamp = TimeInterval.random(in: s...e).rounded()
    let record = ["ax": ax, "ay": ay, "az": az, "timestamp": timestamp]
    data.append(record)
}

Что я получил с print(data as NSArray)?

(
        {
        ax = "-0.9915295335923959";
        ay = "0.04220588780831558";
        az = "0.04947324263041164";
        timestamp = 536480749;
    },
        {
        ax = "0.8339518841345668";
        ay = "-0.8796254984325194";
        az = "0.9274526027609205";
        timestamp = 536596358;
    },
        {
        ax = "0.1892933660394962";
        ay = "0.2786212981444189";
        az = "-0.7010853895168836";
        timestamp = 536453459;
    },
        {
        ax = "-0.3879536539762585";
        ay = "-0.9881198368284949";
        az = "-0.8103733151058379";
        timestamp = 536574669;
    },
        {
        ax = "0.4386373099712233";
        ay = "-0.1082200532953461";
        az = "-0.5452489312143274";
        timestamp = 536515655;
    },
        {
        ax = "0.1021774847462089";
        ay = "-0.6414676993950421";
        az = "0.8826716373674426";
        timestamp = 536455164;
    },
        {
        ax = "0.1877861732407253";
        ay = "-0.6069605631703257";
        az = "-0.3766270018644693";
        timestamp = 536569833;
    },
        {
        ax = "0.3011539934614316";
        ay = "-0.8534914632655413";
        az = "0.652288374381045";
        timestamp = 536477646;
    },
        {
        ax = "-0.3087207248856481";
        ay = "0.566261641115348";
        az = "-0.6320769324182691";
        timestamp = 536563296;
    },
        {
        ax = "-0.5450288945879682";
        ay = "0.6143645223909975";
        az = "-0.8973854689667276";
        timestamp = 536609836;
    }
)

Теперь у меня есть данные в «том же формате», как вы получили (не JSON, а массив словаря Swift) и с небольшой помощью следующей простой функции

// extract date and time from timestamp value
func stamp(timestamp: TimeInterval)->(date: String, time: String) {
    let date = Date(timeIntervalSinceReferenceDate: timestamp)
    return (DateFormatter.localizedString(from: date, dateStyle: .short, timeStyle: .none),
    DateFormatter.localizedString(from: date, dateStyle: .none, timeStyle: .medium))
}

мы готовы сгруппировать ваши значения данных по дате и времени, как требуется

// group data by date and time, if duplicated timestamp, use last value only
let result = data.reduce(into: [String:[String:[String: Double]]]()) { (result, record) in
    guard let ts = record["timestamp"] else { return }
    var record = record
    record["timestamp"] = nil
    let (date, time) = stamp(timestamp: ts)
    if result[date] == nil {
        result[date] = [time : record]
    } else {
        result[date]?[time] = record
    }
}

Посмотрите, как результат [String:[String:[String: Double]]] выглядит напечатанным как NSDictionary

{
    "01/01/2018" =     {
        "00:50:59" =         {
            ax = "0.1892933660394962";
            ay = "0.2786212981444189";
            az = "-0.7010853895168836";
        };
        "01:19:24" =         {
            ax = "0.1021774847462089";
            ay = "-0.6414676993950421";
            az = "0.8826716373674426";
        };
        "07:34:06" =         {
            ax = "0.3011539934614316";
            ay = "-0.8534914632655413";
            az = "0.652288374381045";
        };
        "08:25:49" =         {
            ax = "-0.9915295335923959";
            ay = "0.04220588780831558";
            az = "0.04947324263041164";
        };
        "18:07:35" =         {
            ax = "0.4386373099712233";
            ay = "-0.1082200532953461";
            az = "-0.5452489312143274";
        };
    };
    "02/01/2018" =     {
        "07:21:36" =         {
            ax = "-0.3087207248856481";
            ay = "0.566261641115348";
            az = "-0.6320769324182691";
        };
        "09:10:33" =         {
            ax = "0.1877861732407253";
            ay = "-0.6069605631703257";
            az = "-0.3766270018644693";
        };
        "10:31:09" =         {
            ax = "-0.3879536539762585";
            ay = "-0.9881198368284949";
            az = "-0.8103733151058379";
        };
        "16:32:38" =         {
            ax = "0.8339518841345668";
            ay = "-0.8796254984325194";
            az = "0.9274526027609205";
        };
        "20:17:16" =         {
            ax = "-0.5450288945879682";
            ay = "0.6143645223909975";
            az = "-0.8973854689667276";
        };
    };
}

Часть JSON зависит от вас.

0 голосов
/ 12 ноября 2018
  • jsonResponse - ваш массив

            if let dictionary = jsonResponse as? [String : Any]
            {
    
                        let all=dictionary["Date1"] as? [[String : Any]]
                         if let all = all
                         {
    
                            let user:[String:Any]=all[0]["Time1"]! as! [String : Any]
                            let user2:[String:Any]=all[0]["Time2"]! as! [String : Any]
    
                            print(user["ax"] as? String)!,user["ay"] as? String)!,user["az"] as? String)!)                          
                            print(user2["ax"] as? String)!,user2["ay"] as? String)!,user2["az"] as? String)!)                            
    
                         }
    
            }
    
0 голосов
/ 12 ноября 2018

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

var allData: [OneDayData]

struct OneDayData {
    var date: Date
    var sensorData: [SensorData]
}

struct SensorData {
    var time: String
    var ax: Double
    var ay: Double
    var az: Double
}

Обратите внимание, я не знаю, как вы конвертируете метку времени, поэтому я просто предположил, что она конвертируется в дату и строку

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

Словарь не решит вашу проблему. Здесь вам нужен массив пользовательских моделей.

Например,

struct Time {
    var ax: Float
    var ay: Float
    var az: Float
}

struct Date {
    var times: [Time]
}

let array: [Date] = ... // parse your json into this

Вам нужно записать логику разбора вашего json в эту структуру, что может быть сделано различными способами и, я считаю, выходит за рамки первоначального вопроса

...