Парсинг NSMutableDictionary с требуемым форматом

У меня есть объективный объект C "Obj" с

@property (strong, nonatomic) NSMutableDictionary *obj;

Он заполняется данными из API в следующем формате.

{
  0 =     (  0, "7.00", "8.59”, ”15.00”, ”16.59", "19.00", "20.59 );
  1 =      (  1, "7.00", "8.59”, ”15.00”, ”16.59", "19.00", "20.59  );
  2 =     (  2, "7.00", "8.59”, ”15.00”, ”16.59", "19.00", "20.59  );
  3 =     (  3, "7.00", "8.59”, ”15.00”, ”16.59", "19.00", "20.59  );
  4 =     (  4, "7.00", "8.59”, ”15.00”, ”16.59", "19.00", "20.59  );
  5 =     (  5, "7.00", "8.59”, ”15.00”, ”16.59", "19.00", "20.59  );
  6 =      (  6, "7.00", "8.59”, ”15.00”, ”16.59", "19.00", "20.59 );
}

Мне нужно проанализировать данные и отправить их обратно в виде массива в следующем формате.

`{
[ 0, 7, 00, 8, 59 ],
[0, 15, 00, 16, 59] , 
[0, 19, 00, 20, 59] , 
[ 1, 7, 00, 8, 59 ],
[1, 15, 00, 16, 59] , 
[1, 19, 00, 20, 59], 
……
……
[ 6, 7, 00, 8, 59 ],
[6, 15, 00, 16, 59] , 
[6, 19, 00, 20, 59] 
}`

Где 0,1,2,3,4,5,6 - дни, а остальная информация - часы и минуты. поэтому для каждого слота формат

`[day, from_hour, from_min, to_hour, to_min],
 [0, 7, 0, 8, 59],`

В день может быть несколько слотов или только один.

Пока мне удается запустить цикл и разделить ежедневную запись, как показано ниже.

NSMutableArray *elementArray =[[NSMutableArray alloc ]init];
NSMutableArray *results =[[NSMutableArray alloc ]init];
NSInteger starthour = 0 ;
NSInteger startmin = 0 ;
NSInteger endhour = 0 ;
NSInteger endmin = 0 ;
NSMutableArray *temp = [[NSMutableArray alloc]init];
NSString *string;
int i = 0;
for ( i = 0; i <=6; i ++){
    string = [NSString stringWithFormat:@"%d",i];
    elementArray =[Obj.obj valueForKey:string];
    starthour = [[elementArray objectAtIndex:1]integerValue];
    startmin =([[elementArray objectAtIndex:1]floatValue]-[[elementArray objectAtIndex:1]integerValue])*100;
    endhour = [[elementArray objectAtIndex:2]integerValue];
    endmin =([[elementArray objectAtIndex:2]floatValue]-[[elementArray objectAtIndex:2]integerValue])*100;
    NSNumber *day = [NSNumber numberWithInteger:[string integerValue]];
    NSNumber *starthour1 = [NSNumber numberWithInteger:(int)starthour];
    NSNumber *startmin1 = [NSNumber numberWithInteger:(int)startmin];
    NSNumber *endhour1 = [NSNumber numberWithInteger:(int)endhour];
    NSNumber *endmin1 = [NSNumber numberWithInteger:(int)endmin];
    [temp addObject:day];
    [temp addObject:starthour1];
    [temp addObject:startmin1];
    [temp addObject:endhour1];
    [temp addObject:endmin1];
    [results addObject:temp];
}

Это дает мне доступ к каждой записи. Мой мыслительный процесс говорит, что я мог бы решить эту проблему, просмотрев каждую запись и заполнив требуемый массив как «i» - день, а затем запустив цикл вложенности для каждой записи и извлекая часы и минуты?

Вы получаете информацию в формате JSON или в любом другом формате?

Abdul Rehman 12.10.2018 09:08

Да, я получаю информацию в формате JSON.

humble_pie 12.10.2018 09:09

Поделитесь JSON, чтобы я мог понять вашу проблему

Abdul Rehman 12.10.2018 09:10

{"id" = «1234»; "temp" = "30.85"; obj = {0 = (0, "7.00", "8.59", "15.00", "16.59", "19.00", "20.59); 1 = (1," 7.00 "," 8,59 »,« 15,00 »,« 16,59 »,« 19,00 »,« 20,59 »); 2 = (2, «7,00», «8,59», «15,00», «16,59», «19,00», «20,59»); 3 = (3, «7,00», «8,59», «15,00», «16,59», «19.00», «20.59»); 4 = (4, «7,00», «8,59», «15,00», «16,59», «19,00», «20,59»); 5 = (5, «7,00», «8,59», «15,00», «16,59», «19.00», «20.59»); 6 = (6, «7,00», «8,59», «15,00», «16,59», «19,00», «20,59);};}

humble_pie 12.10.2018 09:17

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

Abdul Rehman 12.10.2018 09:18

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

humble_pie 12.10.2018 09:19

Ok. Но как я могу дать вам какое-либо предложение, не глядя на входные значения

Abdul Rehman 12.10.2018 09:20

Вот как я получаю после NSArray * jsonArray = [NSJSONSerialization JSONObjectWithData: параметры данных: ошибка NSJSONReadingMutableContainers: & error]; Теперь я успешно обновляю несколько текстовых полей данными obj, поступающими с серверов, и эти значения обновляются постоянно обновляющимися записями пользовательского интерфейса и obj, поэтому значения постоянно меняются.

humble_pie 12.10.2018 09:23

@AbdulRehmanWarraich Похоже, это отпечаток NSDictionary, здесь ничего сложного.

Larme 12.10.2018 10:05

попробуйте использовать регулярное выражение. Это спасет ваши дни в будущем.

E.Coms 12.10.2018 15:23
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
86
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы не говорите, какой у вас проблема на самом деле, т.е. вы начали работу над решением, остановились и обратились к SO, почему?

Посмотрим, сможем ли мы помочь вам с помощью некоторого псевдокода.

У вас есть словарь массивов. ключи представляют номера дней, как и первый элемент каждого массива. После первого элемента массива элементы располагаются парами, каждый из которых представляет собой строку, содержащую текстовое представление часов и минут, разделенных точкой. Вам нужен массив массивов, в котором каждый элемент состоит из 5 членов: номер дня, час начала, мин начала, час окончания, минута окончания, все в виде чисел.

Базовый алгоритм решения этой проблемы - это два вложенных цикла. Вам нужно где-то сохранить результат:

results <- new empty array

Теперь вам нужно перебрать свой словарь:

for every key in sourceDictionary
   elementArray = sourceDictionary[key]

[Это цикл, который вы написали, за исключением того, что вы сгенерировали ключи и просмотрели их, а здесь мы извлекаем ключи из словаря. Если вы хотите обрабатывать ключи в определенном порядке, тогда сгенерируйте их в этом порядке или извлеките и отсортируйте их.]

Теперь вам лучше выполнить некоторую проверку данных, elementArray должен содержать как минимум номер дня и одну пару строк, проверьте это:

   check elementArray count > 1 and odd else handle error

Теперь вам нужно обработать каждую пару строк, сначала получить к ним доступ:

   cursor <- 1 // element 0 is the repeated day number
   while cursor < elementArray count do
      startTime <- elementArray[cursor]
      endTime <- elementArray[cursor+1]
      cursor <- cursor + 2 // ready for next iteration

Итак, теперь у вас есть номер дня, key, а также время начала и окончания в виде строки, startTime и endTime. Теперь вам нужно разделить ваши временные строки на полную, возвращая массив подстрок:

      startParts <- startTime split at "."

Еще чеки, две части достали?

      check startParts count is 2 else handle error

Теперь преобразуйте каждую подстроку в целое число:

      startHours <- parse startParts[0] as integer
      startMins <- parse startParts[1] as integer

И продолжайте проверять:

     check startHours in [0, 23] and startMins in [0, 59] else handle error

Теперь у вас есть пять значений, которые вы хотите, добавьте их в свой массив results:

     results <- results append array of (key, startHours, startMins, endHours, endMins)

Теперь просто преобразуйте это в Objective-C и заполните детали. Первый цикл может быть for in, второй - for(init; test; increment). Для разделения строки взгляните на методы NSString, один из них будет соответствовать всем требованиям. Для синтаксического анализа есть несколько вариантов, включая методы NSString.

HTH

int я = 0; сделать {NSLog (@ "% @", [elementArray objectAtIndex: i]); i ++; } в то время как (я <[elementArray count]); Это дает мне каждый день как (1, «7.00», «8.59», «15.00», «16.59», «22.00», «23.59»).

humble_pie 19.10.2018 11:34

@humble_pie Какой у вас вопрос? Из вашего комментария теперь у вас появляется массив массивов, а не словарь массивов (поэтому sourceDictionary в ответе соответствует elementArray в вашем комментарии, а elementArray в ответе соответствует [elementArray objectAtIndex:i] в вашем комментарии). То, что у вас есть NSLog в вашем комментарии, соответствует этапу в ответе, начинающемуся «Теперь вам лучше провести некоторую проверку данных ...». Есть ли что-то после этого, что вызывает у вас трудности? Если да, то что вы пробовали и т. д.

CRD 19.10.2018 13:27

@humble_pie Отредактируйте свой вопрос, чтобы предоставить дополнительную информацию, как указано выше, не надо пытается втиснуть код в комментарии. Вы можете добавить комментарий к этому ответу, указав, что вы добавили информацию к своему вопросу, если хотите.

CRD 19.10.2018 13:30

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

humble_pie 19.10.2018 16:17

У меня все работает, но код выглядит немного запутанным, пожалуйста, посмотрите мой ответ

humble_pie 19.10.2018 17:00

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

` NSMutableArray *elementArray =[[NSMutableArray alloc ]init];
    NSMutableArray *results =[[NSMutableArray alloc ]init];
    NSInteger starthour = 0 ;
    NSInteger startmin = 0 ;
    NSInteger endhour = 0 ;
    NSInteger endmin = 0 ;

    NSNumber *starthour1 ;
    NSNumber *startmin1  ;
    NSNumber *endhour1 ;
    NSNumber *endmin1 ;
    NSMutableArray *temp = [[NSMutableArray alloc]init];
    NSString *string;
    int i = 0;
    for ( i = 0; i <=6; i ++){
        string = [NSString stringWithFormat:@"%d",i];
        elementArray =[Obj.obj valueForKey:string];
        starthour = [[elementArray objectAtIndex:1]integerValue];
        startmin =([[elementArray objectAtIndex:1]floatValue]-[[elementArray objectAtIndex:1]integerValue])*100;
        endhour = [[elementArray objectAtIndex:2]integerValue];
        endmin =([[elementArray objectAtIndex:2]floatValue]-[[elementArray objectAtIndex:2]integerValue])*100;
        NSNumber *day = [NSNumber numberWithInteger:[string integerValue]];
           starthour1 = [NSNumber numberWithInteger:(int)starthour];
           startmin1 = [NSNumber numberWithInteger:(int)startmin];
           endhour1 = [NSNumber numberWithInteger:(int)endhour];
           endmin1 = [NSNumber numberWithInteger:(int)endmin];
        [temp addObject:day];
        [temp addObject:starthour1];
        [temp addObject:startmin1];
        [temp addObject:endhour1];
        [temp addObject:endmin1];
        [results addObject:[temp copy]];



        [temp removeAllObjects];

        starthour = [[elementArray objectAtIndex:3]integerValue];
        startmin =([[elementArray objectAtIndex:3]floatValue]-[[elementArray objectAtIndex:3]integerValue])*100;
        endhour = [[elementArray objectAtIndex:4]integerValue];
        endmin =([[elementArray objectAtIndex:4]floatValue]-[[elementArray objectAtIndex:4]integerValue])*100;

        starthour1 = [NSNumber numberWithInteger:(int)starthour];
        startmin1 = [NSNumber numberWithInteger:(int)startmin];
        endhour1 = [NSNumber numberWithInteger:(int)endhour];
        endmin1 = [NSNumber numberWithInteger:(int)endmin];
        [temp addObject:day];
        [temp addObject:starthour1];
        [temp addObject:startmin1];
        [temp addObject:endhour1];
        [temp addObject:endmin1];
        [results addObject:[temp copy]];



        [temp removeAllObjects];
        starthour = [[elementArray objectAtIndex:5]integerValue];
        startmin =([[elementArray objectAtIndex:5]floatValue]-[[elementArray objectAtIndex:5]integerValue])*100;
        endhour = [[elementArray objectAtIndex:6]integerValue];
        endmin =([[elementArray objectAtIndex:6]floatValue]-[[elementArray objectAtIndex:6]integerValue])*100;

        starthour1 = [NSNumber numberWithInteger:(int)starthour];
        startmin1 = [NSNumber numberWithInteger:(int)startmin];
        endhour1 = [NSNumber numberWithInteger:(int)endhour];
        endmin1 = [NSNumber numberWithInteger:(int)endmin];
        [temp addObject:day];
        [temp addObject:starthour1];
        [temp addObject:startmin1];
        [temp addObject:endhour1];
        [temp addObject:endmin1];
        [results addObject:[temp copy]];



        [temp removeAllObjects];
`

Результат выглядит так, как я хотел.

( ( 0, 7, 0, 8, 59 ), ( 0, 15, 0, 16, 59 ), ( 0, 19, 0, 20, 59 ), ( 1, 7, 0, 8, 59 ), ( 1, 15, 0, 16, 59 ), ( 1, 22, 0, 23, 59 ), ( 2, 7, 0, 8, 59 ), ( 2, 15, 0, 16, 59 ), ( 2, 19, 0, 20, 59 ), ( 3, 7, 0, 8, 59 ), ( 3, 15, 0, 16, 59 ), ( 3, 22, 0, 23, 59 ), ( 4, 7, 0, 8, 59 ), ( 4, 15, 0, 16, 59 ), ( 4, 19, 0, 20, 59 ), ( 5, 7, 0, 8, 59 ), ( 5, 15, 0, 16, 59 ), ( 5, 22, 0, 23, 59 ), ( 6, 7, 0, 8, 59 ), ( 6, 15, 0, 16, 59 ), ( 6, 19, 0, 20, 59 ) )

Похоже, что это работает в соответствии с вашим результатом, так что хорошо сделано. Вы можете подумать, что это неопрятно, но есть еще несколько проблемных моментов. Сначала вы использовали математику с плавающей запятой как часть анализа двух целые числа, которые оказались разделенными точкой. Математика с плавающей запятой работает в двоичном формате, поэтому вы полагаетесь на правильность минутного значения после того, как оно было представлено в виде двоичной дроби (т.е. .59 в виде десятичной дроби составляет 5/10 + 9/100, а в двоичной дроби это 1 / 2 + 1/16 + 1/64 + ...). Намного лучше разбирать целые значения как целые числа. (продолжение)

CRD 19.10.2018 19:01

Затем в своем вопросе вы указали: «В день может быть несколько слотов или только один слот», ваше решение по существу содержит «развернутый цикл», повторяя один и тот же код 3 раза и фиксируя количество слотов на 3. Если у вас есть данные с менее чем 3 временными интервалами ваш код будет ошибочным. Вам лучше проверить количество слотов и использовать цикл, чтобы избежать ошибок и повторения кода. HTH

CRD 19.10.2018 19:01

Да, логика с плавающей запятой не очень хороша. Я потратил больше и 2 часа на то, чтобы найти лучший способ разбить строки после десятичной дроби, но не смог заставить его работать. Что касается вашего второго пункта, я убедился, что в другом месте моего кода всегда указывается 3 временных интервала.

humble_pie 19.10.2018 19:21

Вы можете найти Этот способ полезным.

CRD 19.10.2018 19:29

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