최고의 방법으로 중복 제거하는 값에서 NSMutableArray 하는 것을 목적으?

StackOverflow https://stackoverflow.com/questions/1025674

  •  06-07-2019
  •  | 
  •  

문제

최고의 방법으로 중복 제거하는 값(NSString 에서) NSMutableArray 제공하는 것을 목적으 C?

이것이 가장 쉽고 올바른 방법 그것을 할 수 있나요?

uniquearray = [[NSSet setWithArray:yourarray] allObjects];
도움이 되었습니까?

해결책

당신의 NSSet 객체의 순서에 대해 걱정하지 않으면 접근 방식이 가장 좋습니다. 다시 말하지만, 주문에 대해 걱정하지 않으면 왜 NSSet 우선 첫째로?

나는 2009 년에 아래에 답을 썼다. 2011 년 애플은 덧붙였다 NSOrderedSet iOS 5 및 Mac OS X 10.7에. 알고리즘은 이제 두 줄의 코드입니다.

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 주문에 신경 쓰지 않는 경우.

우리가 사용하는 경우 키 값 코딩의 객체 연산자 우리는 할 수있어:

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

처럼 안토판 또한 속성에 따라 복제물을 제거 할 수 있습니다. 예는 다음과 같습니다. @distinctUnionOfObjects.name

예,사용 중지하는 경우-은 합리적인 접근 방식이다.

추가 짐 Puls'응답,여기에는 다른 방법을 벗기는 중복을 유지하면서 순서는:

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

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

그것은 본질적으로 동일한 접근 방식으로 짐이지만 복사본은 독특한 아이템을 변경할 수 배열보다 중복을 삭제합니다.이것은 그것을 약간 더 효율적인 메모리의 경우에 큰 배열이 많은 중복 항목(필요없이 복사본을 만들의 배열 전체),그리고 내 생각 좀 더 읽을 수 있습니다.

참고는 어느 경우에든지 확인하는 경우 항목은 이미 포함되어 있는 대상에 배열(사용 containsObject: 나의 예제에서,또는 indexOfObject:inRange: 에서 짐)확장을 위해 잘 큰 배열입니다.그 체크에서 실행 O(N)간을 의미하는 경우에 당신은 두 번의 크기를 원래의 배열은 다음 각 검사 것 두 배로 걸리를 실행합니다.기 때문을 다하고 있음을 확인하는 각 개체 배열에,당신은 또한 수 실행하고 더 많은 사람들의 더 비싼 확인합니다.전체적인 알고리즘(모두 광산 및 짐)에서 실행됩 O(N2)시 얻을 수있는,비싼으로 신속하게 원래의 배열을 자랍니다.

그래 O(N)시간에 당신이 사용할 수 있다 NSMutableSet 저장 상품의 이미 추가된 새로운 배열을,이후를 중지하는 경우-조회는 O(1)보다는 오히려 O(N).다시 말해서,체크하지 여부를 확인 요소를 구성원의를 중지하는 경우-같은 시간에 관계없이 많은 요소가에서 설정합니다.

코드를 사용하여 이러한 접근 방법은 다음과 같이 보일 것입니다:

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

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

이것은 여전히 보이는 작은 낭비하지만;우리는 여전히 생성하는 새로운 배열을 때는 질문에는 분명히 원래의 배열의 변경은,그래서 우리는 할 수 있어야 de 속 장소에 저장됩니다.무언가 이것을 좋아한다:

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++;
    }
}

업데이트:Yuri 니야조프 지적 는 나의 마지막 대답은 실제로 실행에 O(N2)기 removeObjectAtIndex: 아마에서 실행됩 O(N)시간입니다.

(그가 말하는"아마"지 않기 때문에 우리는 확실히 알고 어떻게 그것의 구현그러나 하나의 가능한 구현에는 후 삭제하에 있는 객체에 지수 X 방법을 다 루프를 통해 모든 요소 색인에서 X+1 마지막 객체에 배열,이동하는 그들이 이전에 인덱스입니다.이 경우에는 그는 사실 O(N)성능을 제공합니다.)

그래서 무엇을 할까?그것은 상황에 따라 달라집니다.당신은 큰 배열하고,당신은 당신을 기대하고 소수의 복음에 복제이 잘 작동하고 저장할 필요성을 중복 배열입니다.당신은 최상의 많은 중복된 다음 건물까지 별도의 드 속 배열은 아마도 가장 좋은 방법입니다.리기 big-O 표기 유의 특성을 설명하는 알고리즘,그것은 당신에게 말할 것이다 결정적으로 최고의 특정한 상황도 있을 수 있습니다.

OS X V10.7 이상으로 제공됩니다.

주문이 걱정된다면 올바른 방법

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

다음은 nsarray에서 값을 제거하는 코드입니다.

iOS 5+ (전체 iOS 세계를 다루는 것)를 타겟팅하는 경우 최상의 사용 NSOrderedSet. 복제를 제거하고 순서를 유지합니다 NSArray.

그냥 해

NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:yourArray];

이제 독특한 nsarray로 다시 변환 할 수 있습니다.

NSArray *uniqueArray = orderedSet.array;

또는 NSARRAY와 같은 방법을 가지고 있으므로 OrderedSet을 사용하십시오. objectAtIndex:, firstObject 등등.

회원 수표 contains 더 빠릅니다 NSOrderedSet 그것이있을 것보다 NSArray

더 많은 체크 아웃 NSORDEDSET 참조

주문이 필요합니다

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:, 따라서 같은 일련의 글자가 두 번 이상 나타나지 않습니다. newArray. 나는 확실하지 않습니다 NSOrderedSet 솔루션은 값 또는 메모리 위치에 따라 중복을 제거합니다.

내 예제가 가정합니다 sortedSourceArray 그냥 포함됩니다 NSStringS, 그냥 NSMutableStringS 또는 두 사람의 혼합. 만약에 sortedSourceArray 대신 그냥 포함됩니다 NSNumbers 또는 그냥 NSDates, 당신은 교체 할 수 있습니다

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

~와 함께

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

그리고 완벽하게 작동해야합니다. 만약에 sortedSourceArray 혼합을 포함합니다 NSString에스, NSNumberS 및/또는 NSDates, 아마도 충돌 할 것입니다.

보다 우아한 솔루션을 제공하는 KVC 객체 연산자가 있습니다. uniquearray = [yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"]; 여기에 있습니다 NSARRAY 카테고리.

배열에서 개체를 추가하기 전에 중복 값을 추가하지 않는 시도를 시도 할 수있는 한 가지 더 간단한 방법 :-

// mutableAreray가 할당되어 초기화되었다고 가정하고 일부 값을 포함합니다.

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

다음은 nsmutable 배열에서 값을 제거하는 코드입니다.. 그것은 당신을 위해 일할 것입니다. MyArray는 중복 값을 제거하려는 Mutable Array입니다.

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 트릭을 할 것입니다. 이렇게하면 배열에서 복제 제거를 유지하고 정상적으로 설정하지 않는 순서를 유지합니다.

objective-c에서 nsmutablearray에서 중복 값을 제거하십시오

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

이 간단한 코드 만 사용하십시오.

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

NSSET은 중복 값을 허용하지 않으므로 모든 객체가 배열을 반환합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top