지도의 NSRray 등가물
주어진NSArray
의NSDictionary
객체(유사한 객체 및 키 포함) 지정된 키 배열에 맵을 수행할 수 있습니까?예를 들어, 루비에서는 다음과 같은 작업을 수행할 수 있습니다.
array.map(&:name)
몇 줄 밖에 저장되지 않지만 NSRray에서는 카테고리를 사용합니다.블록이 영(0)으로 반환되지 않도록 해야 하지만, 그 외에는 다음과 같은 경우의 시간을 절약할 수 있습니다.-[NSArray valueForKey:]
안 될 겁니다
@interface NSArray (Map)
- (NSArray *)mapObjectsUsingBlock:(id (^)(id obj, NSUInteger idx))block;
@end
@implementation NSArray (Map)
- (NSArray *)mapObjectsUsingBlock:(id (^)(id obj, NSUInteger idx))block {
NSMutableArray *result = [NSMutableArray arrayWithCapacity:[self count]];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[result addObject:block(obj, idx)];
}];
return result;
}
@end
사용법은 다음과 같습니다.-[NSArray enumerateObjectsWithBlock:]
:
NSArray *people = @[
@{ @"name": @"Bob", @"city": @"Boston" },
@{ @"name": @"Rob", @"city": @"Cambridge" },
@{ @"name": @"Robert", @"city": @"Somerville" }
];
// per the original question
NSArray *names = [people mapObjectsUsingBlock:^(id obj, NSUInteger idx) {
return obj[@"name"];
}];
// (Bob, Rob, Robert)
// you can do just about anything in a block
NSArray *fancyNames = [people mapObjectsUsingBlock:^(id obj, NSUInteger idx) {
return [NSString stringWithFormat:@"%@ of %@", obj[@"name"], obj[@"city"]];
}];
// (Bob of Boston, Rob of Cambridge, Robert of Somerville)
Ruby의 기능이 무엇인지는 모르겠지만 NSray에서 구현한 -valueForKey:를 찾고 계신 것 같습니다.전송합니다.-valueForKey:
배열의 모든 요소로 이동하고 결과 배열을 반환합니다.수신 배열의 요소가 NSDictionary일 경우,-valueForKey:
와 거의 같습니다.-objectForKey:
. 키가 시작되지 않는 한 작동합니다.@
다른 모든 답변을 요약하면 다음과 같습니다.
루비(질문에서와 같이):
array.map{|o| o.name}
Obj-C(포함):
[array valueForKey:@"name"];
Obj-C(포함)valueForKeyPath
, KVC 수집 연산자 참조):
[array valueForKeyPath:@"[collect].name"];
Obj-C(포함):
NSMutableArray *newArray = [NSMutableArray array];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[newArray addObject:[obj name]];
}];
array.map { $0.name }
그리고 보다 기능적인 방법으로 어레이를 처리할 수 있는 라이브러리가 몇 개 있습니다.다른 라이브러리를 설치하려면 코코아팟을 설치하는 것이 좋습니다.
업데이트: 스위프트를 사용하는 경우 지도를 참조하십시오.
BlocksKit은 옵션입니다.
NSArray *new = [stringArray bk_map:^id(NSString *obj) {
return [obj stringByAppendingString:@".png"];
}];
밑줄은 또 다른 옵션입니다.있습니다.map
function, 여기 웹사이트의 예가 있습니다.
NSArray *tweets = Underscore.array(results)
// Let's make sure that we only operate on NSDictionaries, you never
// know with these APIs ;-)
.filter(Underscore.isDictionary)
// Remove all tweets that are in English
.reject(^BOOL (NSDictionary *tweet) {
return [tweet[@"iso_language_code"] isEqualToString:@"en"];
})
// Create a simple string representation for every tweet
.map(^NSString *(NSDictionary *tweet) {
NSString *name = tweet[@"from_user_name"];
NSString *text = tweet[@"text"];
return [NSString stringWithFormat:@"%@: %@", name, text];
})
.unwrap;
valueForKeyPath는 좋은 선택이라고 생각합니다.
아래에 앉아 있는 것은 아주 멋진 예들입니다.도움이 되기를 바랍니다.
http://kickingbear.com/blog/archives/9
몇 가지 예:
NSArray *names = [allEmployees valueForKeyPath: @"[collect].{daysOff<10}.name"];
NSArray *albumCovers = [records valueForKeyPath:@"[collect].{artist like 'Bon Iver'}.<NSUnarchiveFromDataTransformerName>.albumCoverImageData"];
저는 Ruby 전문가가 아니기 때문에 100% 정확하게 대답할 자신이 없습니다. 하지만 'map'이 어레이의 모든 것에 어떤 작용을 하며 결과와 함께 새로운 어레이를 생성한다는 해석에 근거하여, 여러분이 원하는 것은 다음과 같습니다.
NSMutableArray *replacementArray = [NSMutableArray array];
[existingArray enumerateObjectsUsingBlock:
^(NSDictionary *dictionary, NSUInteger idx, BOOL *stop)
{
NewObjectType *newObject = [something created from 'dictionary' somehow];
[replacementArray addObject:newObject];
}
];
따라서 OS X 10.6/iOS 4.0의 '블록'(일반적으로 폐쇄)에 대한 새로운 지원을 사용하여 어레이의 모든 것에서 블록 내 작업을 수행하는 것입니다.작업을 수행한 다음 결과를 별도의 배열에 추가하도록 선택합니다.
10.5 또는 iOS 3.x를 지원하는 경우 관련 코드를 개체에 넣고 makeObjectsPerformSelector: 또는 최악의 경우 를 사용하여 배열을 수동으로 반복하는 방법을 고려해 볼 수 있습니다.for(NSDictionary *dictionary in existingArray)
.
@implementation NSArray (BlockRockinBeats)
- (NSArray*)mappedWithBlock:(id (^)(id obj, NSUInteger idx))block {
NSMutableArray* result = [NSMutableArray arrayWithCapacity:self.count];
[self enumerateObjectsUsingBlock:^(id currentObject, NSUInteger index, BOOL *stop) {
id mappedCurrentObject = block(currentObject, index);
if (mappedCurrentObject)
{
[result addObject:mappedCurrentObject];
}
}];
return result;
}
@end
게시된 몇 개의 답변에 대한 약간의 개선.
- 0 확인—0을 사용하여 매핑할 때 개체를 제거할 수 있습니다.
- 메서드 이름은 메서드가 호출된 배열을 수정하지 않는다는 것을 더 잘 나타냅니다.
- 이것은 더 스타일적인 것이지만 IMO는 블록의 인수 이름을 개선했습니다.
- 카운트에 대한 점 구문
Objective-C의 경우, 다음 답변 목록에 ObjectiveSugar 라이브러리를 추가합니다. https://github.com/supermarin/ObjectiveSugar
게다가, 그것의 꼬리표는 "인간을 위한 목적적인 C 추가"입니다.OP에 잘 어울리는 루비 스타일 ;-)
가장 일반적인 사용 사례는 서버 호출에 의해 반환되는 사전을 간단한 개체의 배열에 매핑하는 것입니다. 예를 들어 NSDictionary 게시물에서 NSString ID의 NSray를 가져오는 것입니다.
NSArray *postIds = [results map:^NSString*(NSDictionary* post) {
return [post objectForKey:@"post_id"];
}];
Objective-C의 경우 다음 답변 목록에 Higher-Order-Functions를 추가합니다. https://github.com/fanpyi/Higher-Order-Functions;
JSON 배열 학생 J가 있습니다.SONList는 다음과 같습니다.
[
{"number":"100366","name":"Alice","age":14,"score":80,"gender":"female"},
{"number":"100368","name":"Scarlett","age":15,"score":90,"gender":"female"},
{"number":"100370","name":"Morgan","age":16,"score":69.5,"gender":"male"},
{"number":"100359","name":"Taylor","age":14,"score":86,"gender":"female"},
{"number":"100381","name":"John","age":17,"score":72,"gender":"male"}
]
//studentJSONList map to NSArray<Student *>
NSArray *students = [studentJSONList map:^id(id obj) {
return [[Student alloc]initWithDictionary:obj];
}];
// use reduce to get average score
NSNumber *sum = [students reduce:@0 combine:^id(id accumulator, id item) {
Student *std = (Student *)item;
return @([accumulator floatValue] + std.score);
}];
float averageScore = sum.floatValue/students.count;
// use filter to find all student of score greater than 70
NSArray *greaterthan = [students filter:^BOOL(id obj) {
Student *std = (Student *)obj;
return std.score > 70;
}];
//use contains check students whether contain the student named 'Alice'
BOOL contains = [students contains:^BOOL(id obj) {
Student *std = (Student *)obj;
return [std.name isEqual:@"Alice"];
}];
이를 위한 특별한 키 경로 연산자가 있습니다.@unionOfObjects
. 대체된 것 같습니다.[collect]
이전 버전에서.
상상해보세요.Transaction
와 같은 부류의payee
속성:
NSArray *payees = [self.transactions valueForKeyPath:@"@unionOfObjects.payee"];
배열 연산자에 대한 Apple 문서를 키 값 코딩으로 작성합니다.
스위프트가 새로운 지도 기능을 선보입니다.
다음은 설명서의 예입니다.
let digitNames = [
0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",
5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]
let strings = numbers.map {
(var number) -> String in
var output = ""
while number > 0 {
output = digitNames[number % 10]! + output
number /= 10
}
return output
}
// strings is inferred to be of type String[]
// its value is ["OneSix", "FiveEight", "FiveOneZero"]
맵 함수는 임의 유형의 값을 반환하고 배열의 기존 값을 이 새로운 유형의 인스턴스에 매핑하는 닫힘을 사용합니다.
언급URL : https://stackoverflow.com/questions/6127638/nsarray-equivalent-of-map
'bestsource' 카테고리의 다른 글
줌라 - 500 - 오류가 발생했습니다.SQL 구문에 오류가 있습니다. MariaDB 서버 버전에 해당하는 설명서를 확인하십시오. (0) | 2023.10.31 |
---|---|
처리되지 않은 예외가 발생했습니다. 정의되지 않은 '마이너스' 속성을 읽을 수 없습니다. (0) | 2023.10.31 |
모달 창 내 트위터 부트스트랩 데이트피커 (0) | 2023.10.31 |
Oracle: 스키마 간에 보기를 생성하고 있습니까? (0) | 2023.10.31 |
웹소켓:죽은 후 자동으로 다시 연결하는 방법 (0) | 2023.10.31 |