NSArray를 객관적인 C의 새로운 NSArray로 필터링
-
02-07-2019 - |
문제
나는 가지고있다 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.
}]];
나는 그것이 최대한 간결하다고 생각합니다.
빠른:
함께 일하는 사람들을 위해 NSArray
Swift에서는 이것을 선호할 수도 있습니다 더 나아가 간결한 버전:
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;
}