Быстрое перечисление массивов словарей
У меня есть массив словарей в следующем формате.
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 ответа
Вы можете изменить размер и формат вашего массива, так как ваши данные ясны, просто нужно сделать размер массива равным 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 в массиве.
Как @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