2 NSArrays,根据属性值查找交集?

时间:2014-09-17 12:50:22

标签: ios objective-c nsarray nspredicate nsset

我有两个不同类型的自定义对象的2个NSArray。

对象A属性: ID: 名称: 作者:

对象B属性: BOOKID: 值: 终止子:

我需要过滤“A”类型的对象数组,其ID值等于包含“B”类型对象的第二个数组的任何对象的bookID值。

我试图通过将数组转换为集合来使用intersectSet:方法,但由于这两个对象的类型不同,所以没有任何反应。

进行过滤的最有效方法是什么?我可以指定在进行交叉时要查看的属性吗?

3 个答案:

答案 0 :(得分:12)

以下是示例代码示例:

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);

输出:

intersectionWithBookID: (
        {
        Author = AuthorA1;
        ID = 1;
        Name = NameA1;
    },
        {
        Author = AuthorA3;
        ID = 3;
        Name = NameA3;
    }

答案 1 :(得分:1)

我跳过你的2个NSArray就像

arrayA = ( ObjectA1, ObjectA2, 。 。 ObjectAn )

arrayB = ( ObjectB1, ObjectB2, 。 。 ObjectBn )

在这种情况下,您必须首先使用类似于谓词的ArrayA和arrayB将值提取到单独的数组中

NSPredicate *predicateA = [NSPredicate predicateWithFormat:@"id"];
NSArray *arrayAWithonlyIds = [arrayA filteredArrayUsingPredicate:predicateA];

NSPredicate *predicateB = [NSPredicate predicateWithFormat:@"bookId"];
NSArray *arrayBWithonlyBookIds = [arrayA filteredArrayUsingPredicate:predicateB];

现在你必须将这些仅包含id的结果数组转换为NSSet,以便执行像这样的交集的集合操作

NSMutableset *setResult = [NSMutableSet setWithArray: arrayAWithonlyIds];
[setResult intersectSet:[NSSet setWithArray: arrayBWithonlyBookIds]];

我希望这会给你一个想法。

答案 2 :(得分:0)

我使用NSPredicate过滤数组; 这是代码:

+(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];
}

我创建了作者(A类)和Book(B类)类。这是我的代码的结果

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
希望它有所帮助。