2 NSArrays, find the intersection based on property value?
I have 2 NSArrays from 2 different custom object types.
Properties of object A: ZB: Name: Author:
Object Properties B: BookID: Cost: Terminator:
I need to filter an array of objects of type "A" that has an ID value equal to the bookID value of any of the objects in the second array containing objects of type "B".
I tried to use the intersectSet: method by converting arrays to set, but since both objects are of different type, nothing happened.
What would be the most efficient filtering method? Can I specify properties to view when I do an intersection?
source to share
Here's a sample code with an example:
NSDictionary *dictionaryA1 = @{@"ID":@"1", @"Name":@"NameA1", @"Author":@"AuthorA1"};
NSDictionary *dictionaryA2 = @{@"ID":@"2", @"Name":@"NameA2", @"Author":@"AuthorA2"};
NSDictionary *dictionaryA3 = @{@"ID":@"3", @"Name":@"NameA3", @"Author":@"AuthorA3"};
NSDictionary *dictionaryB0 = @{@"bookID":@"0", @"Name":@"NameB0", @"Author":@"AuthorB0"};
NSDictionary *dictionaryB1 = @{@"bookID":@"1", @"Name":@"NameB1", @"Author":@"AuthorB1"};
NSDictionary *dictionaryB3 = @{@"bookID":@"3", @"Name":@"NameB3", @"Author":@"AuthorB3"};
NSArray *arrayA = @[dictionaryA1, dictionaryA2, dictionaryA3];
NSArray *arrayB = @[dictionaryB0, dictionaryB1, dictionaryB3];
NSArray *intersectionWithBookID = [arrayA filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"ID IN %@", [arrayB valueForKey:@"bookID"]]];
NSLog(@"intersectionWithBookID: %@", intersectionWithBookID);
Output:
intersectionWithBookID: (
{
Author = AuthorA1;
ID = 1;
Name = NameA1;
},
{
Author = AuthorA3;
ID = 3;
Name = NameA3;
}
source to share
I ride your 2 NSArrays like
arrayA = (ObjectA1, ObjectA2,,, ObjectAn)
and
arrayB = (ObjectB1, ObjectB2,,, ObjectBn)
In this case, you must first extract the values into separate arrays using a predicate like this for arrayA and arrayB
NSPredicate *predicateA = [NSPredicate predicateWithFormat:@"id"];
NSArray *arrayAWithonlyIds = [arrayA filteredArrayUsingPredicate:predicateA];
NSPredicate *predicateB = [NSPredicate predicateWithFormat:@"bookId"];
NSArray *arrayBWithonlyBookIds = [arrayA filteredArrayUsingPredicate:predicateB];
Now you need to convert the result array containing only IDs to NSSet inorder in order to perform a set operation such as intersection like this
NSMutableset *setResult = [NSMutableSet setWithArray: arrayAWithonlyIds];
[setResult intersectSet:[NSSet setWithArray: arrayBWithonlyBookIds]];
Hope this gives you an Idea.
source to share
I used NSPredicate to filter the array; here is the code:
+(void)findIntersectionOfAuthors:(NSArray *)authors withBooks:(NSArray *)books
{
NSLog(@"CLASS A");
for (Author * aut in authors)
[aut print];
NSLog(@"CLASS B");
for (Book * b in books)
[b print];
NSMutableArray * resultOfpredicates = [NSMutableArray new];
for (Author * a in authors)
{
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF.bookID == %d", a.authId];//this predicate search field of bookID equality in books array
NSArray * bks = [books copy];
bks = [bks filteredArrayUsingPredicate:predicate];//filters here
if ([bks count])
[resultOfpredicates addObject:a];
}
NSLog(@"RESULT");
for (Author * a in resultOfpredicates)
[a print];
}
I created Author classes (class A) and books (class B). here is the result of my code
2014-09-17 18:10:27.803 Predicate[10725:60b] CLASS A
2014-09-17 18:10:27.803 Predicate[10725:60b] id:100 name:1 author:23
2014-09-17 18:10:27.803 Predicate[10725:60b] id:100 name:2 author:24
2014-09-17 18:10:27.804 Predicate[10725:60b] id:102 name:1 author:25
2014-09-17 18:10:27.804 Predicate[10725:60b] id:109 name:1 author:26
2014-09-17 18:10:27.804 Predicate[10725:60b] id:101 name:1 author:27
2014-09-17 18:10:27.805 Predicate[10725:60b] CLASS B
2014-09-17 18:10:27.805 Predicate[10725:60b] bookId:100 value:12 term:12
2014-09-17 18:10:27.805 Predicate[10725:60b] bookId:101 value:13 term:13
2014-09-17 18:10:27.805 Predicate[10725:60b] bookId:102 value:13 term:13
2014-09-17 18:10:27.806 Predicate[10725:60b] bookId:103 value:13 term:13
2014-09-17 18:10:27.806 Predicate[10725:60b] bookId:104 value:13 term:13
2014-09-17 18:10:27.808 Predicate[10725:60b] RESULT
2014-09-17 18:10:27.809 Predicate[10725:60b] id:100 name:1 author:23
2014-09-17 18:10:27.809 Predicate[10725:60b] id:100 name:2 author:24
2014-09-17 18:10:27.809 Predicate[10725:60b] id:102 name:1 author:25
2014-09-17 18:10:27.809 Predicate[10725:60b] id:101 name:1 author:27
hope this helps.
source to share