如何从目标c中的模型数组内的模型数组中搜索单词

时间:2016-02-18 10:38:32

标签: ios objective-c search nsarray nspredicate

从另一个模型数组中的模型数组中搜索单词的最佳和最简单的方法是什么。例如,我有一个包含学生模型类的数组。因此,学生有不止一位教师,这是一系列教师模范课程。当我搜索教师姓名时,我需要获得拥有该教师的学生名单。我知道如何使用模型类数组中的predicate进行搜索。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",@"sarah"];
searchArray = [NSMutableArray arrayWithArray:[studentArray filteredArrayUsingPredicate:predicate]];

我尝试了这个,但它没有用。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.teachers.teacherName contains[c] %@",@"sarah"];

学生模型类将如下所示。

@property (nonatomic, assign) NSString *name;
@property (nonatomic, strong) NSString *address;
@property (strong, nonatomic) NSArray *teachers;

我知道如何通过拆分数组并使用for循环来实现它。任何人都可以帮我找到一个最简单的方法。谢谢。

3 个答案:

答案 0 :(得分:1)

好吧,比如你提到的,你的模型类具有以下属性, 例如在Student.h文件

 #import <Foundation/Foundation.h>

 @interface Student : NSObject
 @property (nonatomic, strong) NSString *name; //i am changing it to strong 
 @property (nonatomic, strong) NSString *address;
 @property (strong, nonatomic) NSArray *teachers;
 - (id)initWithName:(NSString *)name trachers:(NSArray *)teachers address:(NSString *)address;
 @end

Student.m档案

#import "Student.h"
@implementation Student

//custom initialiser 
- (id)initWithName:(NSString *)name trachers:(NSArray *)teachers address:(NSString *)address
{
    if(self = [super init])
    {
       self.name = name;
       self.teachers = teachers;
       self.address = address;
    }
    return self;
}
@end

并在ViewController.m文件中我创建了Student的实例并将其添加到数组中,例如,

ViewController.h文件中,

#import <UIKit/UIKit.h>
#import "Student.h"
@property (nonatomic, strong) NSMutableArray *students; //to hold student instances
@property (weak, nonatomic) IBOutlet UISearchBar *searchBar;//to search the teachers 
@property (weak, nonatomic) IBOutlet UITextView *textView;//to display the output
@end

并在ViewController.m文件中,

#import "ViewController.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
 {
   [super viewDidLoad];
   _students = [[NSMutableArray alloc] init];
   for(int k = 0 ; k < 5 ; k++)
   {
       NSMutableArray *teachers = [self getTeachersForStudent:k];//a helper method to fill teacher's name
       Student *stud = [[Student alloc] initWithName:[NSString stringWithFormat:@"student_%d",k] trachers:teachers address:[NSString stringWithFormat:@"address_%d",k]]; //hear student name will be like "student_0"
       [_students addObject:stud]; //finally add it to students array
   }
}

//this is the helper method, for testing u can add different same name if you want 
- (NSMutableArray *)getTeachersForStudent:(int)k
{
    NSMutableArray *array = [[NSMutableArray alloc] init];
    switch (k)
    {
       case 0:
           [array addObjectsFromArray:@[@"anoop",@"shan",@"sara",@"peter",@"david",@"gopi"]];
       break;
       case 1:
           [array addObjectsFromArray:@[@"hema",@"isah",@"sara",@"john"]];
       break;
       case 2:
           [array addObjectsFromArray:@[@"venu",@"giri",@"kim",@"madu",@"shan"]];
       break;
       case 3:
           [array addObjectsFromArray:@[@"venu",@"tom",@"yesh",@"vijay",@"shan"]];
       break;
       case 4:
           [array addObjectsFromArray:@[@"vim",@"janu",@"jai",@"kiran",@"shan"]];
       break;
       default:
          break;
   }
   return array;
 }

最后在ViewController.m文件中添加以下方法的排序功能,它将从搜索栏中取出初始字符串并搜索所有教师名称,最后给出将在textview中显示的学生姓名

 - (void)refreshStudentList
  {
     __block NSMutableArray *result = [[NSMutableArray alloc] init];
     [_students enumerateObjectsUsingBlock:^(Student*  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
      __block Student *presentStudent = obj;
      __block NSArray *array = [presentStudent valueForKey:@"teachers"];
      [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
           if([obj rangeOfString:self.searchBar.text options:NSCaseInsensitiveSearch].location != NSNotFound)
            {
                [result addObject:presentStudent];
            }
      }];
   }];
  //at this point result array contains all the student student name of the teacher that u are searched 
   NSString *resultString = @"";
   for(Student *s in result)
   {
      resultString = [NSString stringWithFormat:@"%@ \n %@", resultString, s.name];
   }
   _textView.text = resultString;
 }

在同一ViewController.m中添加searhbar委托方法并调用refreshStudentList方法

 - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
 {
    [self refreshStudentList];
    if (searchText.length == 0)
       _textView.text = @"";  //simply resetting the text view 
}

最后输出将如下所示

enter image description here

答案 1 :(得分:0)

尝试下面的代码段。它会起作用

NSArray *allIds = YOURARRAY
__block NSMutableArray *newArray = [[NSMutableArray alloc] init];
[allIds enumerateObjectsUsingBlock:^(NSArray* obj, NSUInteger idx, BOOL *stop) {

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",@"sarah"];
        searchArray = [NSMutableArray arrayWithArray:[studentArray filteredArrayUsingPredicate:predicate]];
       [newArray addObject:searchArray];
}];
NSLog(@"%d", [newArray count]);

答案 2 :(得分:0)

您可以在NSPredicate中使用KVC运算符,执行以下操作:

predicate =
  [NSPredicate predicateWithFormat:@"teachers.lastName CONTAINS %@", @"Petter" ];
filtered  = [studentsArray filteredArrayUsingPredicate:predicate];

@mattt在他们的NSHipster文章(http://nshipster.com/kvc-collection-operators/)中写了一个很好的例子,关于集合中的KVC运算符,这可能对你有用。