2009-07-10 2 views
3

, 그것은 쉬웠다 :NSDictionary에서 임의의 키를 선택하려면 어떻게해야합니까? 내가있는 NSArray를 사용하여 때

NSArray *array = ... 
lastIndex = INT_MAX; 
... 
int randomIndex; 
do { 
    randomIndex = RANDOM_INT(0, [array count] - 1); 
} while (randomIndex == lastIndex); 
NSLog(@"%@", [array objectAtIndex:randomIndex]); 
lastIndex = randomIndex; 

은 내가 난수의 느낌을 원하기 때문에는 lastIndex 추적 할 필요가있다. 즉, 같은 요소를 두 번 연속으로 가져오고 싶지 않습니다. 따라서 "진정한"임의성이 있어서는 안됩니다.

내가 말할 수있는 것부터 NSDictionary에는 -objectAtIndex :와 같은 것이 없습니다. 그럼 어떻게해야합니까?

답변

2

allKeys (정의되지 않은 순서) 또는 keysSortedByValueUsingSelector (값으로 정렬하려는 경우) 키 배열을 가져올 수 있습니다. (lastIndex와 관련하여) 염두에 두어야 할 한 가지 점은 정렬을해도 사전이 커질 때 동일한 인덱스가 다른 키 - 값 쌍을 참조 할 수 있다는 것입니다.

이들 중 하나 (특히 keysSortedByValueUsingSelector)는 성능 저하를 가져옵니다.

편집 : 사전을 변경할 수 없으므로 allKeys를 한 번 호출 한 다음 그 키에서 임의 키를 선택하면됩니다. 당신이 인스턴스 변수에 keys을 캐시 할 수 있습니다,

- (YourObjectType *)getRandomObjectFromDictionary:(NSDictionary *)dictionary 
{ 
    NSArray *keys = dictionary.allKeys; 
    return dictionary[keys[arc4random_uniform((int)keys.count)]]; 
} 

가보다 효율적으로 만들려면 :

+0

NSDictionary (NSMutableDictionary가 아닌)이므로 성장하지 않을 것입니다. 그것은 [[NSDictionary alloc] initWithObjectsAndKeys : ..., nil]을 사용하여 앱 실행시 명시 적으로 생성됩니다. – Elliot

+0

그것은 작동합니다. 내가 한 일은 allKeys를 한 번 호출하여 새로운 NSArray ivar에 저장하는 것입니다. NSDictionary가 변경되지 않은 경우에도 allKeys가 항상 동일한 순서로 키를 반환하지 않을 수도 있습니다. 하지만 NSArray를 리턴 값으로 가리킬 때 아무런 문제가 없기를 바랍니다. – Elliot

+0

귀하의 경우에 allKeys 반환 값을 유지하는 데 문제가있는 것은 아닙니다. 새로운 배열이 할당되므로 결과는 내부 데이터 구조를 직접 가리 키지 않습니다. –

1

아래의 코드를 사용할 수 있습니다. 희망이 도움이됩니다.

관련 문제