답변:
NSArray
및 NSMutableArray
필터 어레이 목차 방법을 제공한다. 지정된 술어와 일치하는 수신자의 오브젝트를 포함하는 새 배열을 리턴하는 filtersArrayUsingPredicate : 를 NSArray
제공합니다 . filterUsingPredicate : 추가 : 지정된 조건 자에 대해 수신자의 콘텐츠를 평가하고 일치하는 개체 만 남겨 둡니다. 이러한 방법은 다음 예제에 설명되어 있습니다.NSMutableArray
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.
}]];
나는 그것이 얻는 것처럼 간결하다고 생각합니다.
NSArray
Swift에서 s로 작업하는 사람들 은 이보다 간결한 버전을 선호 할 수 있습니다 .
nsArray = nsArray.filter { $0.shouldIKeepYou() }
filter
Array
( NSArray
은 암시 적으로 Swift에 연결 되는 방법입니다 Array
). 하나의 인수를 취합니다 : 배열에서 하나의 객체를 취하고 Bool
. 클로저 true
에서 필터링 된 배열에서 원하는 객체를 반환하십시오 .
NSPredicate predicateWithBlock:
API에 필요 합니다.
bindings
사전에는 템플릿에 대한 변수 바인딩이 포함될 수 있습니다.
Clay Bridges의 답변에 따라 다음은 블록을 사용한 필터링의 예입니다 ( yourArray
배열 변수 이름과 testFunc
테스트 함수 이름으로 변경 ).
yourArray = [yourArray objectsAtIndexes:[yourArray indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [self testFunc:obj];
}]];
filteredArrayUsingPredicate
더 간결 하지만 어떤 술어도 사용하지 않는다는 사실은 목적을 모호하게합니다.
Implicit conversion of 'NSUInteger' (aka 'unsigned long') to 'NSIndexSet * _Nonnull' is disallowed with ARC
... NSIndexSets 예상
indexOfObjectPassingTest
은 indexesOfObjectsPassingTest
. 놓치기 쉽지만 큰 차이점 :)
OS X 10.6 / iOS 4.0 이상인 경우 NSPredicate보다 블록을 사용하는 것이 좋습니다. 보다-[NSArray indexesOfObjectsPassingTest:]
또는 편리한 추가 자신의 범주를 쓰기 -select:
또는 -filter:
방법 ( 예 ).
다른 사람이 해당 카테고리를 작성하고 테스트하는 등의 작업을 원하십니까? BlocksKit ( array docs )을 확인하십시오 . 그리고 거기에 많은 예를 들어 검색 말하자면 찾을 수 더 많은 예제, "NSArray를 블록 카테고리 선택이" .
객체가 모두 유사한 유형이라고 가정하면 기준에 사용중인 함수를 호출하는 기본 클래스의 범주로 메서드를 추가 할 수 있습니다. 그런 다음 해당 메서드를 참조하는 NSPredicate 개체를 만듭니다.
일부 범주에서 함수를 사용하는 방법을 정의하십시오.
@implementation BaseClass (SomeCategory)
- (BOOL)myMethod {
return someComparisonFunction(self, whatever);
}
@end
그런 다음 필터링 할 위치 :
- (NSArray *)myFilteredObjects {
NSPredicate *pred = [NSPredicate predicateWithFormat:@"myMethod = TRUE"];
return [myArray filteredArrayUsingPredicate:pred];
}
물론 함수가 클래스 내에서 도달 할 수있는 속성과 만 비교하는 경우 함수의 조건을 조건 자 문자열로 변환하는 것이 더 쉬울 수 있습니다.
NSPredicate
(컬렉션을 필터링 조건을 구성하는 넥스트 스텝의 방법입니다 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 %'와 같은 column1- >NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@",@"c"];
3) select * from tbl where column1 like '% a %' ->
[NSMutableArray arrayWithArray:[arr filteredArrayUsingPredicate:predicate]];
이게 도움이 되길 바란다
NSArray + Xh
@interface NSArray (X)
/**
* @return new NSArray with objects, that passing test block
*/
- (NSArray *)filteredArrayPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate;
@end
NSArray + Xm
@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;
}];