Быстрое перечисление массивов словарей - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть массив словарей в следующем формате.

myarary = {день = 0; час = 1; значение = 0;}, {день = 0; час = 2; значение = 0;} .... {день 6 = 1; час = 23; значение = 1;}

Таким образом, в основном 7 дней, 24 часа для каждого дня и значения 1 или 0 для каждого часа. следовательно, в моем массиве всего 168 словарей.

Теперь моя задача - извлечь значения для диапазона часов для данного дня. Например, для 6-го дня мне нужно было бы извлечь интервал часов между 2, 9 и другой интервал между 15 и 18 и т. Д.

Мне удалось решить проблему с помощью гнезда для цикла в следующем формате

for (i =< start_of_hour_slot;i=<last_hour_of_slot); i++) for(j = 0; j<=6; j++)

Теперь это работает, но он слишком длинный и мой код заполнен циклами, должен быть более простой способ с быстрым перечислением?

Во-вторых, мои циклы for не дают мне гибкости.

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

или, может быть, на несколько дней, например, день 3,4,5 слотов 2-9, 11,15 ...

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Как сказал @vadian, NSCompoundPredicate должен работать для того, чего вы пытаетесь достичь. Похоже, что у вас есть несколько опечаток в NSP-предикате, который вы опубликовали в своих комментариях, поэтому он не может разобрать.

#import "ViewController.h"

@interface ViewController ()
@property (strong, nullable) NSArray <NSDictionary *> *generatedArray;
- (NSArray <NSDictionary *> *)_generateFakeDictionaryArray;
- (NSPredicate *)_predicateForDays:(NSArray <NSNumber *> *)days andHours:(NSArray <NSNumber *> *)hours;
- (NSPredicate *)_predicateForDays:(NSArray <NSNumber *> *)days andHoursBetween:(NSArray <NSNumber *> *)hoursBetween;
- (NSPredicate *)_predicateForDaysBetween:(NSArray <NSNumber *> *)daysBetween andHours:(NSArray <NSNumber *> *)hours;
- (NSPredicate *)_predicateForDaysBetween:(NSArray <NSNumber *> *)daysBetween andHoursBetween:(NSArray <NSNumber *> *)hoursBetween;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.generatedArray = [self _generateFakeDictionaryArray];
}

- (void)viewDidAppear:(BOOL)animated {
    // one day multiple hour slots
    NSPredicate *specificDaysSpecificHours = [self _predicateForDays:@[@(6)] andHours:@[@(7), @(8), @(22)]];
    // multiple days hoursBetween
    NSPredicate *daysBetweenHoursBetween = [self _predicateForDaysBetween:@[@(3), @(5)] andHoursBetween:@[@(2), @(9)]];
    // days between, specific hours
    NSPredicate *daysBetweenSpecificHours = [self _predicateForDaysBetween:@[@(3), @(5)] andHours:@[@(11), @(15)]];
    NSCompoundPredicate *compPred = [NSCompoundPredicate orPredicateWithSubpredicates:@[specificDaysSpecificHours, daysBetweenHoursBetween, daysBetweenSpecificHours]];
    NSArray <NSDictionary *> *filteredArray = [self.generatedArray filteredArrayUsingPredicate:compPred];
    NSLog(@"Filtered array = %@", filteredArray);
}

- (NSArray <NSDictionary *> *)_generateFakeDictionaryArray {
    NSInteger daysInWeek = 7;
    NSInteger hoursInDay = 24;
    NSMutableArray *dictArray = [NSMutableArray arrayWithCapacity:hoursInDay * daysInWeek];
    for (NSInteger day = 0; day < daysInWeek; day++) {
        for (NSInteger hour = 0; hour < hoursInDay; hour++) {
            NSDictionary *dayHourDict = @{@"day" : @(day), @"hour" : @(hour), @"value" : @(arc4random() % 2)};
            [dictArray addObject:dayHourDict];
        }
    }
    return [NSArray arrayWithArray:dictArray];
}

- (NSPredicate *)_predicateForDays:(NSArray <NSNumber *> *)days andHours:(NSArray <NSNumber *> *)hours {
    return [NSPredicate predicateWithFormat:@"day IN %@ AND hour IN %@", days, hours];
}

- (NSPredicate *)_predicateForDays:(NSArray <NSNumber *> *)days andHoursBetween:(NSArray <NSNumber *> *)hoursBetween {
    return [NSPredicate predicateWithFormat:@"day IN %@ AND hour BETWEEN %@", days, hoursBetween];
}

- (NSPredicate *)_predicateForDaysBetween:(NSArray <NSNumber *> *)daysBetween andHours:(NSArray <NSNumber *> *)hours {
    return [NSPredicate predicateWithFormat:@"day BETWEEN %@ AND hour IN %@", daysBetween, hours];
}

- (NSPredicate *)_predicateForDaysBetween:(NSArray <NSNumber *> *)daysBetween andHoursBetween:(NSArray <NSNumber *> *)hoursBetween {
    return [NSPredicate predicateWithFormat:@"day BETWEEN %@ AND hour BETWEEN %@", daysBetween, hoursBetween];
}


@end

, который генерирует это как вывод:

Filtered array = (
        {
        day = 3;
        hour = 2;
        value = 1;
    },
        {
        day = 3;
        hour = 3;
        value = 0;
    },
        {
        day = 3;
        hour = 4;
        value = 0;
    },
        {
        day = 3;
        hour = 5;
        value = 1;
    },
        {
        day = 3;
        hour = 6;
        value = 0;
    },
        {
        day = 3;
        hour = 7;
        value = 0;
    },
        {
        day = 3;
        hour = 8;
        value = 0;
    },
        {
        day = 3;
        hour = 9;
        value = 1;
    },
        {
        day = 3;
        hour = 11;
        value = 0;
    },
        {
        day = 3;
        hour = 15;
        value = 1;
    },
        {
        day = 4;
        hour = 2;
        value = 1;
    },
        {
        day = 4;
        hour = 3;
        value = 1;
    },
        {
        day = 4;
        hour = 4;
        value = 1;
    },
        {
        day = 4;
        hour = 5;
        value = 1;
    },
        {
        day = 4;
        hour = 6;
        value = 1;
    },
        {
        day = 4;
        hour = 7;
        value = 1;
    },
        {
        day = 4;
        hour = 8;
        value = 0;
    },
        {
        day = 4;
        hour = 9;
        value = 1;
    },
        {
        day = 4;
        hour = 11;
        value = 1;
    },
        {
        day = 4;
        hour = 15;
        value = 1;
    },
        {
        day = 5;
        hour = 2;
        value = 1;
    },
        {
        day = 5;
        hour = 3;
        value = 0;
    },
        {
        day = 5;
        hour = 4;
        value = 1;
    },
        {
        day = 5;
        hour = 5;
        value = 0;
    },
        {
        day = 5;
        hour = 6;
        value = 0;
    },
        {
        day = 5;
        hour = 7;
        value = 1;
    },
        {
        day = 5;
        hour = 8;
        value = 1;
    },
        {
        day = 5;
        hour = 9;
        value = 0;
    },
        {
        day = 5;
        hour = 11;
        value = 0;
    },
        {
        day = 5;
        hour = 15;
        value = 1;
    },
        {
        day = 6;
        hour = 7;
        value = 1;
    },
        {
        day = 6;
        hour = 8;
        value = 1;
    },
        {
        day = 6;
        hour = 22;
        value = 1;
    }
)

https://developer.apple.com/documentation/foundation/nspredicate?language=objc

https://developer.apple.com/documentation/foundation/nscompoundpredicate?language=objc

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html#//apple_ref/doc/uid/TP40001789

0 голосов
/ 07 сентября 2018

Вы можете изменить размер и формат вашего массива, так как ваши данные ясны, просто нужно сделать размер массива равным 168 и поместить значение 0 или 1 непосредственно в массив. Первые 24 элемента содержат массив значений day0, а следующие 24 элемента - значения day1, ..., последние 24 элемента - значения day6. Если вы хотите извлечь значения слотов дня 3,4,5 2-9, 11,15, просто выберите индекс элементов 3 * 6 + 2 ~ 3 * 6 + 9, 4 * 6 + 11, 5 * 6. +15 в массиве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...