Objective-C избирателно попълва таблица от plist; ако ключът е равен

plist1 е масив от 40 речника, с 4 низа всеки. plist2 също е масив, но от 120 речника с по 2 низа всеки.

Ако изброя всички отбори в хокейна лига в таблица (попълнена от определен ключ в plist1), кажете, че избирам петия надолу. Това избутва нова маса. 120-те речника в plist2 имат два низа - всеки има по един за една година от историята на лигата в ред и един за това кой е спечелил шампионата тази година. Искам тази втора таблица да изброява само годините, за които вторият ключ на речника е същото име на екип, което току-що беше избрано в първата таблица, plist1. Така че, когато избера отбор "5" от първата маса, бих очаквал да видя само годините, които отбор "5" е спечелил във втората таблица. Идеята е, че всички години ще присъстват в plist2, но неподходящите ще бъдат блокирани в действителната таблица в движение.

Как мога да кажа "ако потребителят е избрал отбор X, тогава показва годините само за отбор X, а не всички години."

Благодаря ти!


person naweinberger    schedule 24.11.2011    source източник


Отговори (1)


Всъщност можете да направите този вид филтриране доста добре, като използвате NSPredicate:

NSDictionary *testA = [NSDictionary dictionaryWithObjectsAndKeys:@"valA", @"key1", @"1", @"key2", nil];
NSDictionary *testB = [NSDictionary dictionaryWithObjectsAndKeys:@"valB", @"key1", @"2", @"key2", nil];
NSDictionary *testC = [NSDictionary dictionaryWithObjectsAndKeys:@"valC", @"key1", @"1", @"key2", nil];
NSDictionary *testD = [NSDictionary dictionaryWithObjectsAndKeys:@"valD", @"key1", @"3", @"key2", nil];

NSArray *testArr = [NSArray arrayWithObjects:testA, testB, testC, testD, nil];

NSPredicate *pred = [NSPredicate predicateWithFormat:@"key2 == %@", @"1"];
NSArray *testFilter = [testArr filteredArrayUsingPredicate:pred];

NSLog(@"%@", testFilter);

Тази настройка създава 4 речника и масив от тях. Филтърният израз сега търси всички съдържащи се обекти, където key2 е равно на 1, което трябва да бъде testA и testC. И това е изходът:

2011-11-24 18:57:07.822 testapp[9977:f803] (
        {
        key1 = valA;
        key2 = 1;
    },
        {
        key1 = valC;
        key2 = 1;
    }
)

По този начин можете да създадете предикат за филтриране по името на вашия екип и да създадете филтрирана версия на вашия масив. Като цяло това работи на всички видове обекти, които поддържат кодиране на ключ-стойност (което NSDictionary прави, допълнителна информация за това: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/BasicPrinciples.html#//apple_ref/doc/uid/20002170)

person Dennis Bliefernicht    schedule 24.11.2011
comment
Благодаря ви за отговора! Има ли някакъв начин да използвам съществуващия си масив в plist-овете, вместо да създавам нови речници в кода? Може би бих могъл да им се обадя...? Направих това с първата таблица, като направих това: - (void)viewDidLoad { [super viewDidLoad]; NSString *path = [[NSBundle mainBundle] pathForResource:@"ChronoWSH" ofType:@"plist"]; NSArray* tmpArray = [[NSArray alloc] initWithContentsOfFile:path]; self.chronologicallyArray = tmpArray; [tmpArray release]; след това cell.textLabel.text = [[self.chronologicallyArray objectAtIndex:indexPath.row] objectForKey:YEAR_KEY]; - person naweinberger; 24.11.2011
comment
Разбира се, речниците бяха там само за създаване на примери. Във вашия код ще започнете от реда NSPredicate и ще използвате filteredArrayUsingPredicate директно във вашия собствен plist масив. - person Dennis Bliefernicht; 24.11.2011
comment
Това има смисъл, благодаря. Последното нещо, което не разбирам, е @"key2==%@", @"1"]; Какво да поставя там, за да се уверя, че програмата зарежда правилния низ, тъй като низът ще варира според екипа. Трябва да е променлива. Ще трябва ли да го настроя, като кажа, че key2 е името на отбора и че key2 трябва да е равен на низа от името? Доста съм неопитен, благодаря за търпението. - person naweinberger; 24.11.2011
comment
key2 е ключът, използван в речника за филтриране. Предполагам, че вашият речник е настроен по начин, че има ключ, наречен като име на екип, и ключова година със съответните стойности. Тогава ще поставите teamname вместо key2 и можете да използвате променлива за името на отбора, което да бъде филтрирано, вместо константата @"1" в моя пример. - person Dennis Bliefernicht; 24.11.2011
comment
Добре, съжалявам, просто не съм сигурен как да дефинирам тази променлива. Трябва ли да създам NSString за didSelectRowAtIndexPath и след това да включа този NSString като моя променлива? - person naweinberger; 24.11.2011
comment
Ако разбирам правилно концепцията на приложението ви, ще предадете избраното име на екипа от първия контролер на изгледа (списъка с екипи) към втория изглед (филтрирания списък по име на екип). След това контролерът за изглед на филтриран списък ще създаде в своя метод viewDidLoad филтрирано копие на масива и ще го съхрани локално въз основа на тази променлива, подобно на това, което правите в първата си таблица в коментара по-горе. Контролерът за филтриран изглед вече има свой собствен филтриран списък и може да го показва директно, сякаш няма друг списък. - person Dennis Bliefernicht; 24.11.2011
comment
Мисля, че го разбирате правилно, но можете ли да ми дадете пример за действително предаване на името от един контролер на изглед към друг? Самото създаване на променлива за избрания екип и след това включването й в новата таблица е извън мен. Съжалявам! - person naweinberger; 24.11.2011
comment
Няма проблем, очертах стъпките в друга нишка за предаване на NSDate обект между контролери за изглед. Може би това е достатъчно полезно: stackoverflow.com/questions/8258735/ - person Dennis Bliefernicht; 24.11.2011
comment
Страхувам се, че все още съм малко объркан. В първия ми TableViewController имам екипния масив (alphabeticallyArray), дефиниран в .h и синтезиран в .m. Имам и масив, наречен selectedTeam, който има @property и е синтезиран. DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil]; detailViewController.alphabeticallyArray = selectedTeam; - person naweinberger; 25.11.2011
comment
Току-що го промених малко, ако не сте прочели горния коментар, пренебрегнете го: AlphabeticallyTableViewController *alphabeticallyTVC = [AlphabeticallyTableViewController alloc]; alphabeticallyTVC.alphabeticallyArray = selectedTeam; DetailViewController е това, което наричам контролер на втората таблица. - person naweinberger; 25.11.2011
comment
Винаги можете да заредите своя масив във втория изглед. но имате нужда от името на екипа като свойство NSString. Ако приемем, че сте декларирали и синтезирали свойство teamName и dataArray във вашия подробен изглед. Във вашия viewDidLoad нещо подобно: `(void)viewDidLoad { [super viewDidLoad]; NSString path = [[NSBundle mainBundle] pathForResource:@secondFilePlist ofType:@plist]; NSArray tmpArray = [[NSArray alloc] initWithContentsOfFile:path]; self.dataArray = [tmpArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@teamname == %@, self.teamName]]; [tmpArray освобождаване];`` - person Dennis Bliefernicht; 25.11.2011
comment
Много благодаря! Това изглежда е точно това, от което се нуждая! Оценявам вашата помощ! - person naweinberger; 26.11.2011