문제

나는 가지고있다 NSArray 그리고 저는 새로운 것을 만들고 싶습니다 NSArray 특정 기준을 충족하는 원래 배열의 객체로.기준은 다음을 반환하는 함수에 의해 결정됩니다. BOOL.

나는 NSMutableArray, 소스 배열을 반복하고 필터 함수가 허용하는 객체를 복사한 다음 변경할 수 없는 버전을 만듭니다.

더 좋은 방법이 있나요?

도움이 되었습니까?

해결책

NSArray 그리고 NSMutableArray 배열 내용을 필터링하는 방법을 제공합니다. NSArray 제공한다 filteredArrayUsingPredicate: 이는 지정된 조건자와 일치하는 수신기의 개체를 포함하는 새 배열을 반환합니다. NSMutableArray 추가하다 filterUsingPredicate: 이는 지정된 조건자에 대해 수신자의 콘텐츠를 평가하고 일치하는 객체만 남깁니다.이러한 방법은 다음 예에 설명되어 있습니다.

NSMutableArray *array =
    [NSMutableArray arrayWithObjects:@"Bill", @"Ben", @"Chris", @"Melissa", nil];

NSPredicate *bPredicate =
    [NSPredicate predicateWithFormat:@"SELF beginswith[c] 'b'"];
NSArray *beginWithB =
    [array filteredArrayUsingPredicate:bPredicate];
// beginWithB contains { @"Bill", @"Ben" }.

NSPredicate *sPredicate =
    [NSPredicate predicateWithFormat:@"SELF contains[c] 's'"];
[array filteredArrayUsingPredicate:sPredicate];
// array now contains { @"Chris", @"Melissa" }

다른 팁

이를 수행하는 방법은 많지만 지금까지 가장 좋은 방법은 확실히 다음을 사용하는 것입니다. [NSPredicate predicateWithBlock:]:

NSArray *filteredArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) {
    return [object shouldIKeepYou];  // Return YES for each object you want in filteredArray.
}]];

나는 그것이 최대한 간결하다고 생각합니다.


빠른:

함께 일하는 사람들을 위해 NSArraySwift에서는 이것을 선호할 수도 있습니다 더 나아가 간결한 버전:

nsArray = nsArray.filter { $0.shouldIKeepYou() }

filter 에 대한 방법 일뿐입니다 Array (NSArray 암시적으로 Swift와 연결됩니다. Array).하나의 인수가 필요합니다.배열에서 하나의 객체를 가져와서 반환하는 클로저 Bool.클로저에서 그냥 돌아오세요 true 필터링된 배열에서 원하는 모든 개체에 대해.

OS X 10.6/iOS 4.0 이상이라면 NSPredicate보다 블록을 사용하는 것이 더 나을 것입니다.보다 -[NSArray indexesOfObjectsPassingTest:] 또는 자신만의 카테고리를 작성하여 편리한 추가 -select: 또는 -filter: 방법 ().

다른 사람이 해당 카테고리를 작성하고 테스트해 주기를 원하시나요?확인해 보세요 블록킷 (배열 문서).그리고 거기에 많은 예를 들어 다음을 검색하여 더 많은 예를 찾을 수 있습니다. "nsarray 블록 카테고리 선택".

Clay Bridges의 답변을 바탕으로 다음은 블록을 사용하여 필터링하는 예입니다(변경 yourArray 배열 변수 이름과 testFunc 테스트 기능의 이름으로):

yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
    return [self testFunc:obj];
}]];

개체가 모두 비슷한 유형이라고 가정하면 기준에 사용하는 함수를 호출하는 기본 클래스의 범주로 메서드를 추가할 수 있습니다.그런 다음 해당 메서드를 참조하는 NSPredicate 개체를 만듭니다.

일부 카테고리에서는 함수를 사용하는 방법을 정의하십시오.

@implementation BaseClass (SomeCategory)
- (BOOL)myMethod {
    return someComparisonFunction(self, whatever);
}
@end

그런 다음 필터링할 위치는 다음과 같습니다.

- (NSArray *)myFilteredObjects {
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMethod = TRUE"];
    return [myArray filteredArrayUsingPredicate:pred];
}

물론 함수가 클래스 내에서 도달할 수 있는 속성과만 비교하는 경우 함수의 조건을 조건자 문자열로 변환하는 것이 더 쉬울 수 있습니다.

NSPredicate 컬렉션을 필터링하기 위한 조건을 구성하는 nextstep의 방법입니다(NSArray, NSSet, NSDictionary).

예를 들어 두 개의 배열을 고려해보세요 arr 그리고 filteredarr:

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

filteredarr = [NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];

Filterarr에는 반드시 문자 c만 포함된 항목이 있을 것입니다.

SQL에 대한 배경 지식이 부족한 사람들도 쉽게 기억할 수 있도록 하기 위해

*--select * from tbl where column1 like '%a%'--*

1) tbl에서 *를 선택합니다. --> 수집

2)'%a%'와 같은 열 1 --> NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];

3) 열 1이 '%a%'와 같은 tbl에서 *를 선택합니다. -->

[NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];

이게 도움이 되길 바란다

NSArray+X.h

@interface NSArray (X)
/**
 *  @return new NSArray with objects, that passing test block
 */
- (NSArray *)filteredArrayPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate;
@end

NSArray+X.m

@implementation NSArray (X)

- (NSArray *)filteredArrayPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate
{
    return [self objectsAtIndexes:[self indexesOfObjectsPassingTest:predicate]];
}

@end

이 카테고리는 여기에서 다운로드할 수 있습니다

이 라이브러리를 확인해 보세요

https://github.com/BadChoice/Collection

다시는 루프를 작성하지 않는 쉬운 배열 함수가 많이 제공됩니다.

그래서 당신은 할 수 있습니다 :

NSArray* youngHeroes = [self.heroes filter:^BOOL(Hero *object) {
    return object.age.intValue < 20;
}];

또는

NSArray* oldHeroes = [self.heroes reject:^BOOL(Hero *object) {
    return object.age.intValue < 20;
}];

가장 쉽고 쉬운 방법은 이 메서드를 만들고 배열과 값을 전달하는 것입니다.

- (NSArray *) filter:(NSArray *)array where:(NSString *)key is:(id)value{
    NSMutableArray *temArr=[[NSMutableArray alloc] init];
    for(NSDictionary *dic in self)
        if([dic[key] isEqual:value])
            [temArr addObject:dic];
    return temArr;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top