source

Objective-C의 NSMutableArray에서 중복된 값을 제거하는 가장 좋은 방법은 무엇입니까?

nicesource 2023. 4. 19. 23:12
반응형

Objective-C의 NSMutableArray에서 중복된 값을 제거하는 가장 좋은 방법은 무엇입니까?

값을 ( 「」 「」 「」 「」NSString부터의 설명NSMutableArray★★★★★★★★★★★★★★★★★★★★★★★?

이게 가장 쉽고 올바른 방법인가요?

uniquearray = [[NSSet setWithArray:yourarray] allObjects];

의 ★★★★★★★★★★★★★★★★★.NSSet라고 하는 에는 어프로치가 되지 않는 에는 어프로치라고 하는 것은 사물의 가 걱정되지 않는 경우에는 해 두는요?NSSet★★★★★★★★★★★★★★★★★★?

과 같이 은 【2009】【2009】【2011년】NSOrderedSetOS 5 (Mac OS X 10.7)알고리즘이었던 것이 현재는 코드 2행입니다.

NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:yourArray];
NSArray *arrayWithoutDuplicates = [orderedSet array];

주문이 걱정되고 iOS 4 이전 버전에서 실행 중인 경우 어레이 복사본을 루프하십시오.

NSArray *copy = [mutableArray copy];
NSInteger index = [copy count] - 1;
for (id object in [copy reverseObjectEnumerator]) {
    if ([mutableArray indexOfObject:object inRange:NSMakeRange(0, index)] != NSNotFound) {
        [mutableArray removeObjectAtIndex:index];
    }
    index--;
}
[copy release];

질문인 , 중복되는 이 있습니다.NSArray 주문에 신경 쓴다면요

Key Value Coding에서 Object Operators를 사용하면 다음과 같은 작업을 수행할 수 있습니다.

uniquearray = [yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"];

AntoPak이 지적했듯이 속성을 기반으로 중복을 제거할 수 있습니다.예를 들어 다음과 같습니다.@distinctUnionOfObjects.name

네, NSSet을 사용하는 것은 현명한 접근법입니다.

Jim Puls의 답변에 덧붙이자면, 질서를 유지하면서 중복된 부분을 제거하는 다른 방법이 있습니다.

// Initialise a new, empty mutable array 
NSMutableArray *unique = [NSMutableArray array];

for (id obj in originalArray) {
    if (![unique containsObject:obj]) {
        [unique addObject:obj];
    }
}

기본적으로 Jim과 동일한 접근 방식이지만 중복된 항목을 원본에서 삭제하지 않고 새로운 가변 어레이에 복사합니다.이것에 의해, 중복이 많은 대규모 어레이(어레이 전체의 카피를 작성할 필요가 없음)의 경우, 메모리의 효율이 약간 향상해, 조금 더 읽기 쉽다고 생각합니다.

되어 있는지 해 주세요를 사용해 주세요).containsObject:예에서는, 또는 「 」의 「 」를 참조해 주세요.indexOfObject:inRange:Jim's)는 대규모 어레이에 적합하지 않습니다.이러한 체크는 O(N)시간 내에 실행됩니다.즉, 원래 어레이의 크기를 2배로 하면체크의 실행 시간이 2배로 길어집니다.어레이 내의 각 오브젝트에 대한 체크를 하기 때문에 더 많은 비용이 드는 체크를 실행할 수 있습니다.전체 알고리즘(내 알고리즘과 Jim 알고리즘 모두)은 O(N2) 시간에 실행되며, 원래 어레이의 확장에 따라 비용이 빠르게 증가합니다.

) O(N)를 합니다.NSMutableSetNSSet 조회가 O(N)가 아닌 O(1)이므로 새 배열에 이미 추가된 항목의 레코드를 저장합니다. 내의 같은 .

이 방법을 사용하는 코드는 다음과 같습니다.

NSMutableArray *unique = [NSMutableArray array];
NSMutableSet *seen = [NSMutableSet set];

for (id obj in originalArray) {
    if (![seen containsObject:obj]) {
        [unique addObject:obj];
        [seen addObject:obj];
    }
}

다만, 이것은 아직 조금 낭비라고 생각됩니다.원래 어레이는 변경 가능한 것이 판명되었을 때, 아직 새로운 어레이를 생성하고 있기 때문에, 중복을 배제하고 메모리를 절약할 수 있을 것입니다.다음과 같은 경우:

NSMutableSet *seen = [NSMutableSet set];
NSUInteger i = 0;

while (i < [originalArray count]) {
    id obj = [originalArray objectAtIndex:i];

    if ([seen containsObject:obj]) {
        [originalArray removeObjectAtIndex:i];
        // NB: we *don't* increment i here; since
        // we've removed the object previously at
        // index i, [originalArray objectAtIndex:i]
        // now points to the next object in the array.
    } else {
        [seen addObject:obj];
        i++;
    }
}

업데이트: 유리 니야조프는 내 마지막 답변은 실제로 O(N2)로 실행된다고 지적했다. 왜냐하면removeObjectAtIndex:O(N)로 하다

(실장 방법을 확실히 알 수 없기 때문에 "아마도"라고 말합니다.그러나 가능한 구현 방법 중 하나는 인덱스 X에서 오브젝트를 삭제한 후 메서드가 인덱스 X+1에서 어레이의 마지막 오브젝트까지 모든 요소를 루프하여 이전 인덱스로 이동하는 것입니다.이것이 사실이라면 O(N) 퍼포먼스입니다.

그럼 어떻게 해야 하죠?상황에 따라 다르죠.대규모 어레이가 있고 중복되는 수가 적은 경우, 인플레이스 중복 제거는 정상적으로 동작하므로 중복 어레이를 구축할 필요가 없습니다.중복되는 어레이가 많은 경우 중복 배제된 어레이를 개별적으로 구축하는 것이 가장 좋은 방법입니다.여기서 중요한 것은 빅 O 표기법은 알고리즘의 특성만을 나타낼 뿐, 주어진 상황에서 어떤 것이 최선인지 명확하게 알 수 없다는 것입니다.

iOS 5+(iOS 세계 전체를 커버하는 것)를 타겟으로 하고 있는 경우는, 최적인 사용법NSOrderedSet되는 것을 하고, 자신의 유지합니다.NSArray.

그냥 해

NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:yourArray];

이제 고유 NSArray로 변환할 수 있습니다.

NSArray *uniqueArray = orderedSet.array;

Set은 가 있기 을 사용합니다.objectAtIndex:,firstObject기타 등등.

★★★★★★★★★★★★★★★★★★★★★의 멤버십 체크contains NSOrderedSet에 있는 보다 더NSArray

자세한 체크아웃을 위해 NSOrenderedSet 참조

OS X v10.7 이후에 사용 가능.

만약 당신이 주문에 대해 걱정된다면, 올바른 방법

NSArray *no = [[NSOrderedSet orderedSetWithArray:originalArray]allObjects];

다음은 NSArray에서 중복된 값을 제거하는 코드입니다.

질서가 필요하다

NSArray *yourarray = @[@"a",@"b",@"c"];
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:yourarray];
NSArray *arrayWithoutDuplicates = [orderedSet array];
NSLog(@"%@",arrayWithoutDuplicates);

또는 순서가 필요 없음

NSSet *set = [NSSet setWithArray:yourarray];
NSArray *arrayWithoutOrder = [set allObjects];
NSLog(@"%@",arrayWithoutOrder);

여기서 mainArray에서 중복된 이름 값을 삭제하고 결과를 NSMutableArray(listOfUsers)에 저장합니다.

for (int i=0; i<mainArray.count; i++) {
    if (listOfUsers.count==0) {
        [listOfUsers addObject:[mainArray objectAtIndex:i]];

    }
   else if ([[listOfUsers valueForKey:@"name" ] containsObject:[[mainArray objectAtIndex:i] valueForKey:@"name"]])
    {  
       NSLog(@"Same object");
    }
    else
    {
        [listOfUsers addObject:[mainArray objectAtIndex:i]];
    }
}

정렬된 배열이 있는 경우 배열 내의 다른 모든 항목과 비교할 필요가 없으며 마지막 항목만 확인할 필요가 없습니다.모든 항목을 확인하는 것보다 훨씬 빠를 것입니다.

// sortedSourceArray is the source array, already sorted
NSMutableArray *newArray = [[NSMutableArray alloc] initWithObjects:[sortedSourceArray objectAtIndex:0]];
for (int i = 1; i < [sortedSourceArray count]; i++)
{
    if (![[sortedSourceArray objectAtIndex:i] isEqualToString:[sortedSourceArray objectAtIndex:(i-1)]])
    {
        [newArray addObject:[tempArray objectAtIndex:i]];
    }
}

그 모양은...NSOrderedSet권장되는 답변은 훨씬 적은 코드를 필요로 하지만,NSOrderedSet어떤 이유에서인지, 그리고 당신은 정렬된 어레이를 가지고 있습니다. 제 솔루션이 가장 빠를 거라고 생각합니다.그 속도와 비교가 안 될 것 같아요.NSOrderedSet그리고 는 '체크' 입니다.isEqualToString:는 1번 newArray. 나는 잘 모르겠다.NSOrderedSet값 또는 메모리 위치에 따라 중복이 제거됩니다.

에서는 「」를 전제로 하고 .sortedSourceArray 들어맞다NSString just s, 냥 sNSMutableString또는 둘의 혼재입니다. ifsortedSourceArray, "" " " " " 을 포함합니다.NSNumber 또는 그냥 " " " 입니다. "NSDates로 바꿀 수 .

if (![[sortedSourceArray objectAtIndex:i] isEqualToString:[sortedSourceArray objectAtIndex:(i-1)]])

와 함께

if ([[sortedSourceArray objectAtIndex:i] compare:[sortedSourceArray objectAtIndex:(i-1)]] != NSOrderedSame)

완벽하게 작동해야 합니다. ifsortedSourceArray재재 of NSStrings,NSNumber "/"NSDate아마 크래쉬 할 거예요

우아한 uniquearray = [yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"];여기 NSArray 카테고리가 있습니다.

어레이에 개체를 추가하기 전에 중복 값이 추가되지 않는 방법을 시도해 볼 수 있습니다.-

//변환 가능한 어레이가 할당 및 초기화되어 있으며 일부 값이 포함되어 있다고 가정합니다.

if (![yourMutableArray containsObject:someValue])
{
   [yourMutableArray addObject:someValue];
}

Objective-C의 NSMutableArray에서 중복된 값 제거

NSMutableArray *datelistArray = [[NSMutableArray alloc]init];
for (Student * data in fetchStudentDateArray)
{
    if([datelistArray indexOfObject:data.date] == NSNotFound)
    [datelistArray addObject:data.date];
}

NSMutable Array에서 중복된 값을 삭제하는 코드는 다음과 같습니다.사용할 수 있습니다.myArray는 중복된 값을 삭제하는 변환 가능한 어레이입니다.

for(int j = 0; j < [myMutableArray count]; j++){
    for( k = j+1;k < [myMutableArray count];k++){
    NSString *str1 = [myMutableArray objectAtIndex:j];
    NSString *str2 = [myMutableArray objectAtIndex:k];
    if([str1 isEqualToString:str2])
        [myMutableArray removeObjectAtIndex:k];
    }
 } // Now print your array and will see there is no repeated value

「」를 사용합니다.Orderedset이렇게 from , remove duplicates가 되고 정상적으로설정되지 순서됩니다.

다음 간단한 코드를 사용합니다.

NSArray *hasDuplicates = /* (...) */;
NSArray *noDuplicates = [[NSSet setWithArray: hasDuplicates] allObjects];

nsset은 중복된 값을 허용하지 않으며 모든 개체는 어레이를 반환하므로

언급URL : https://stackoverflow.com/questions/1025674/the-best-way-to-remove-duplicate-values-from-nsmutablearray-in-objective-c

반응형