NSMutableArray를 사용하는 2D 어레이
-
05-09-2019 - |
문제
목표 c에서 변한 2 차원 배열을 만들어야합니다.
예를 들어 나는 다음과 같습니다.
NSMutableArray *sections;
NSMutableArray *rows;
각 항목 sections
배열로 구성됩니다 rows
. rows
객체를 포함하는 배열입니다.
그리고 나는 다음과 같은 일을하고 싶습니다.
[ sections[i] addObject: objectToAdd]; //I want to add a new row
Section 0, Rows : OBJ1, OBJ2, OBJ3 섹션 1, 행 : OBJ4, OBJ5, OBJ6, OBJ 7 ...
Objective-C에서 그렇게하는 방법이 있습니까?
해결책
먼저 사용하기 전에 객체를 할당하고 초기화해야합니다. NSMutableArray * sections = [[NSMutableArray alloc] initWithCapacity:10];
행의 경우 하나가 아닌 각각에 대해 하나의 객체가 필요합니다. NSMutableArray * rows;
둘째, Xcode 4.4+를 사용하는지 여부에 따라 section[i]
& section[i] = …
) 사용해야 할 수도 있습니다 [sections objectAtIndex:i]
읽기와 [section replaceObjectAtIndex:i withObject: objectToAdd]
글쓰기를 위해.
셋째, 배열에는 구멍, 즉 OBJ1, NIL, OBJ2가 없을 수 있습니다. 모든 색인에 실제 객체를 제공해야합니다. 아무것도 넣지 않아도 사용할 수 있습니다. NSNull
물체.
또한 대상 C 객체를 일반 C 어레이에 저장할 수도 있다는 것을 잊지 마십시오.
id table[lnum][rnum];
table[i][j] = myObj;
다른 팁
배열을 사용 하여이 작업을 수행하려면 귀하는 sections
배열, 다음과 같이 행 배열을 추가하십시오.
NSMutableArray *sections = [[NSMutableArray alloc] init];
NSMutableArray *rows = [[NSMutableArray alloc] init];
//Add row objects here
//Add your rows array to the sections array
[sections addObject:rows];
특정 인덱스 에이 행 객체를 추가하려면 다음을 사용하십시오.
//Insert your rows array at index i
[sections insertObject:rows atIndex:i];
그런 다음 배열을 검색 하여이 행 배열을 수정할 수 있습니다.
//Retrieve pointer to rows array at index i
NSMutableArray *rows = [sections objectAtIndex:i]
//modify rows array here
항상 자신의 수업을 만들 수 있습니다 Section
, NSMutableArray
회원 전화 rows
; 그런 다음 행을이 배열 안에 저장하고 Section
배열의 개체 :
@interface Section : NSObject {
NSMutableArray *rows;
}
그런 다음 단순히 만듭니다 Section
항목, 클래스 내에서 행 항목을 추가/제거하는 메소드를 만들 수 있습니다. 그런 다음 모든 것을 포장합니다 Sections
다른 배열 내부의 항목 :
Section *aSection = [[Section alloc] init];
//add any rows to your Section instance here
NSMutableArray *sections = [[NSMutableArray alloc] init];
[sections addObject:aSection];
각각에 대해 더 많은 속성을 추가하려면 더 유용합니다. Section
사례.
이 언어는 다차원 객체 지향 어레이를 지원하지 않지만 다음과 같이 nsmutablearrays로 가득 찬 nsmutablearray를 사용하는 클래스를 만들 수 있습니다. 나는 이것이나 무엇이든 컴파일을 시도하지 않았고, 방금 입력했습니다.
@interface SectionArray : NSObject {
NSMutableArray *sections;
}
- initWithSections:(NSUInteger)s rows:(NSUInteger)r;
+ sectionArrayWithSections:(NSUInteger)s rows:(NSUInteger)r;
- objectInSection:(NSUInteger)s row:(NSUInteger)r;
- (void)setObject:o inSection:(NSUInteger)s row:(NSUInteger)r;
@end
@implementation SectionArray
- initWithSections:(NSUInteger)s rows:(NSUInteger)r {
if ((self = [self init])) {
sections = [[NSMutableArray alloc] initWithCapacity:s];
NSUInteger i;
for (i=0; i<s; i++) {
NSMutableArray *a = [NSMutableArray arrayWithCapacity:r];
for (j=0; j<r; j++) {
[a setObject:[NSNull null] atIndex:j];
}
[sections addObject:a];
}
}
return self;
}
+ sectionArrayWithSections:(NSUInteger)s rows:(NSUInteger)r {
return [[[self alloc] initWithSections:s rows:r] autorelease];
}
- objectInSection:(NSUInteger)s row:(NSUInteger)r {
return [[sections objectAtIndex:s] objectAtIndex:r];
}
- (void)setObject:o inSection:(NSUInteger)s row:(NSUInteger)r {
[[sections objectAtIndex:s] replaceObjectAtIndex:r withObject:0];
}
@end
당신은 이것을 사용합니다 :
SectionArray *a = [SectionArray arrayWithSections:10 rows:5];
[a setObject:@"something" inSection:4 row:3];
id sameOldSomething = [s objectInSection:4 row:3];
도대체. 우리 가이 질문을 되 살리고있는 한, 여기에 문자 컬렉션 구문의 시대와 시각적 형식 해석에 대한 무언가가 있습니다!
누구나 궁금한 점이 있으면 다음과 같습니다.
NSMutableArray *multi = [@[ [@[] mutableCopy] , [@[] mutableCopy] ] mutableCopy];
multi[1][0] = @"Hi ";
multi[1][1] = @"There ";
multi[0][0] = @"Oh ";
multi[0][1] = @"James!";
NSLog(@"%@%@%@%@", multi[0][0], multi[1][0], multi[1][1], multi[0][1]);
결과 : "오 안녕 제임스!"
물론, 같은 것을 시도하는 문제가 있습니다. multi[3][5] = @"?"
유효하지 않은 인덱스 예외를 얻으므로 NSMutableArray에 대한 카테고리를 작성했습니다.
@interface NSMutableArray (NullInit)
+(NSMutableArray *)mutableNullArrayWithSize:(NSUInteger)size;
+(NSMutableArray *)mutableNullArraysWithVisualFormat:(NSString *)string;
@end
@implementation NSMutableArray (NullInit)
+(NSMutableArray *)mutableNullArrayWithSize:(NSUInteger)size
{
NSMutableArray *returnArray = [[NSMutableArray alloc] initWithCapacity:size];
for (int i = 0; i < size; i++) {
[returnArray addObject:[NSNull null]];
}
return returnArray;
}
+(NSMutableArray *)mutableNullArraysWithVisualFormat:(NSString *)string
{
NSMutableArray *returnArray = nil;
NSRange bitRange;
if ((bitRange = [string rangeOfString:@"^\\[\\d+]" options:NSRegularExpressionSearch]).location != NSNotFound) {
NSUInteger size = [[string substringWithRange:NSMakeRange(1, bitRange.length - 2)] integerValue];
if (string.length == bitRange.length) {
returnArray = [self mutableNullArrayWithSize:size];
} else {
returnArray = [[NSMutableArray alloc] initWithCapacity:size];
NSString *nextLevel = [string substringWithRange:NSMakeRange(bitRange.length, string.length - bitRange.length)];
NSMutableArray *subArray;
for (int i = 0; i < size; i++) {
subArray = [self mutableNullArraysWithVisualFormat:nextLevel];
if (subArray) {
[returnArray addObject:subArray];
} else {
return nil;
}
}
}
} else {
return nil;
}
return returnArray;
}
@end
보시다시피, 우리는 배열을 가득 채울 수있는 편의 방법이 있습니다. NSNull
거친 포기로 지수를 설정할 수 있습니다.
둘째, 다음과 같은 시각적 형식으로 문자열을 구문 분석하는 재귀 메소드가 있습니다. [3][12]
(3 x 12 배열). 어떤 방식 으로든 문자열이 유효하지 않으면 메소드가 반환됩니다. nil
, 그러나 유효한 경우 지정한 크기의 전체 다차원 배열을 얻습니다.
여기 몇 가지 예가 있어요.
NSMutableArray *shrub = [NSMutableArray mutableNullArrayWithSize:5];
NSMutableArray *tree = [NSMutableArray mutableNullArraysWithVisualFormat:@"[3][12]"]; // 2-Dimensional Array
NSMutableArray *threeDeeTree = [NSMutableArray mutableNullArraysWithVisualFormat:@"[3][5][6]"]; // 3-Dimensional Array
NSMutableArray *stuntedTree = [NSMutableArray mutableNullArraysWithVisualFormat:@"[6][4][k]"]; // Returns nil
원하는만큼의 치수를 시각적 형식 방법으로 전달한 다음 Literal Syntax로 다음과 같이 액세스 할 수 있습니다.
NSMutableArray *deepTree = [NSMutableArray mutableNullArraysWithVisualFormat:@"[5][3][4][2][7]"];
deepTree[3][2][1][0][5] = @"Leaf";
NSLog(@"Look what's at 3.2.1.0.5: %@", deepTree[3][2][1][0][5]);
어쨌든, 이것을 다른 무엇보다 운동으로 더 많이 사용했습니다. 아마도 대상 C 객체 포인터의 다차원 배열을 만드는 방법을 고려할 때 그것은 그랜드 사물의 계획에서 매우 효율적 일 것입니다.
그의 코드에 대한 Jack 덕분에 나는 그것에 대해 조금 일했다. 내 프로젝트 중 하나에 문자열을위한 다차원 NSMutableArray가 필요합니다. 여전히 고정해야 할 것이 있지만 지금은 현악기에만 작동하는 것들이 있습니다. 여기에 게시하겠습니다. 제안을 위해 열려 있습니다. 현재 객관적인 C에서 ...
@interface SectionArray : NSObject {
NSMutableArray *sections;
}
- initWithSections:(NSUInteger)intSections:(NSUInteger)intRow;
+ sectionArrayWithSections:(NSUInteger)intSections:(NSUInteger)intRows;
- objectInSection:(NSUInteger)intSection:(NSUInteger)intRow;
- (void)setObject:(NSString *)object:(NSUInteger)intSection:(NSUInteger)intRow;
@end
@implementation SectionArray
- initWithSections:(NSUInteger)intSections:(NSUInteger)intRow {
NSUInteger i;
NSUInteger j;
if ((self = [self init])) {
sections = [[NSMutableArray alloc] initWithCapacity:intSections];
for (i=0; i < intSections; i++) {
NSMutableArray *a = [NSMutableArray arrayWithCapacity:intRow];
for (j=0; j < intRow; j++) {
[a insertObject:[NSNull null] atIndex:j];
}
[sections addObject:a];
}
}
return self;
}
- (void)setObject:(NSString *)object:(NSUInteger)intSection:(NSUInteger)intRow {
[[sections objectAtIndex:intSection] replaceObjectAtIndex:intRow withObject:object];
}
- objectInSection:(NSUInteger)intSection:(NSUInteger)intRow {
return [[sections objectAtIndex:intSection] objectAtIndex:intRow];
}
+ sectionArrayWithSections:(NSUInteger)intSections:(NSUInteger)intRows {
return [[self alloc] initWithSections:intSections:intRows] ;
}
@end
이것은 잘 작동합니다 !!!
나는 현재 이렇게 사용하고 있습니다
SectionArray *secA = [[SectionArray alloc] initWithSections:2:2];
[secA setObject:@"Object":0:0];
[secA setObject:@"ObjectTwo":0:1];
[secA setObject:@"ObjectThree":1:0];
[secA setObject:@"ObjectFour":1:1];
NSString *str = [secA objectInSection:1:1];
NSLog(@" object is = %@" , str);
다시 감사합니다 잭 !!
참고 : Jack의 코드는 작동하기 전에 많은 작업이 필요합니다. 다른 문제들 중에서도 자동 제조물은 액세스하기 전에 데이터를 릴리스하게 만들 수 있으며 그의 사용법은 클래스 메소드 배열을 호출합니다 : 행 : 실제로 섹션 arraywithsections : 행으로 정의됩니다.
기회가 생기면 나중에 실제 작업 코드를 게시하려고 할 수 있습니다.
오래된 스레드를 부활 시키지만 Jack의 코드를 재 작업했습니다. 1. 1. 컴파일하고 2. 2d C 배열 [행] [열]이 [섹션 (열)] [행] 대신 2d C 순서입니다. 당신은 간다!
twodarray.h :
#import <Foundation/Foundation.h>
@interface TwoDArray : NSObject
@property NSMutableArray *rows;
- initWithRows:(NSUInteger)rows columns:(NSUInteger)columns;
+ sectionArrayWithRows:(NSUInteger)rows columns:(NSUInteger)columns;
- objectInRow:(NSUInteger)row column:(NSUInteger)column;
- (void)setObject:(id)obj inRow:(NSUInteger)row column:(NSUInteger)column;
@end
twodarray.m :
#import "TwoDArray.h"
@implementation TwoDArray
- (id)initWithRows:(NSUInteger)rows columns:(NSUInteger)columns {
if ((self = [self init])) {
self.rows = [[NSMutableArray alloc] initWithCapacity: rows];
for (int i = 0; i < rows; i++) {
NSMutableArray *column = [NSMutableArray arrayWithCapacity:columns];
for (int j = 0; j < columns; j++) {
[column setObject:[NSNull null] atIndexedSubscript:j];
}
[self.rows addObject:column];
}
}
return self;
}
+ (id)sectionArrayWithRows:(NSUInteger)rows columns:(NSUInteger)columns {
return [[self alloc] initWithRows:rows columns:columns];
}
- (id)objectInRow:(NSUInteger)row column:(NSUInteger)column {
return [[self.rows objectAtIndex:row] objectAtIndex:column];
}
- (void)setObject:(id)obj inRow:(NSUInteger)row column:(NSUInteger)column {
[[self.rows objectAtIndex:row] replaceObjectAtIndex:column withObject:obj];
}
@end
이것이 배열 배열을 초기화하기 위해 내가 한 일입니다.
NSMutableArray *arrayOfArrays = [[NSMutableArray alloc] initWithCapacity:CONST];
for (int i=0; i<=CONST; i++) {
[arrayOfArrays addObject:[NSMutableArray array]];
}
그런 다음 나중에 코드에서 나는 간단히 할 수 있습니다.
[[arrayOfArrays objectAtIndex:0] addObject:myObject];