2013-01-03 56 views
1

我有鍵/值的數組...從包含陣列交錯鍵構建的NSDictionary和清潔路值

NSArray *keysAndValues = @[@"1", @"one", @"2", @"two", @"3", @"three"]; 

什麼是將此轉換爲一個NSDictionary所以最簡單的方式,它的字典匹配看起來像......

NSDictionary *dict = @{@"1" : @"two", @"2" : @"two", @"3" : @"three"}; 

我有一些代碼,只是通過數組循環並提取鍵/值,但我想知道如果有一個更清潔的方式或任何內置NSDictionary方法,我失蹤?

+2

可惜你沒有鍵和值倒置,或者你可以使用[NSDictionary dictionaryWithObjectsAndKeys:] –

+1

@FernandoMazzon,如果BeachRunnerFred確實有他的鍵和值倒置,他會如何使用'dictionaryWithObjectsAndKeys'?我自己嘗試過,但'dictionaryWithObjectsAndKeys'請求一個以nil結尾的以逗號分隔的對象列表,而我無法弄清楚如何使用指定的數組。 –

+2

要回答你的問題,我不認爲有任何其他便利方法已經爲此目的而定義。您可能需要繼續使用當前提取鍵/值和字典中的設置的方式。 – iDev

回答

3

您不會錯過任何東西。除了循環以外,沒有任何真正方便的方法。當然,任何解決方案的根源都是循環的,但如果有更多的「過濾」或重新安排的能力嵌入到NSArray(/我謹慎地咳嗽並查看Python列表解析),那將是很好的選擇。

GitHub上的vikingosegundo's arraytools或其他人的類似收集操作擴展可能在此方面有用。在編寫自己的類別方法來做這件事情時肯定沒有什麼壞處,但是,就像我所說的那樣,在那裏必須有一個循環。

這是我的建議,無論什麼值得。通過枚舉它拆分數組:

NSMutableArray * keys = [NSMutableArray array]; 
NSMutableArray * values = [NSMutableArray array]; 
[array enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop)){ 
    if(idx % 2){ 
     [values addObject:obj]; 
    else { 
     [keys addObject:obj]; 
    } 
}]; 

NSDictionary * d = [NSDictionary dictionaryWithObjects:values forKeys:keys]; 

好像應該有更好的方式來做到這一點,如與NSIndexSetobjectsAtIndexes:,但有創建具有非連續一堆設定的指標沒有方便的方法的指標。

這樣的事情,例如,將是不錯:

@implementation NSIndexSet (WSSNonContiguous) 


+ (id) WSS_indexSetWithOddIndexesInRange: (NSRange)range 
{ 
    NSMutableIndexSet * s = [NSMutableIndexSet indexSet]; 

    // If the start of the range is even, start with the next number. 
    NSUInteger start = range.location % 2 ? range.location : range.location + 1; 
    NSUInteger upper_limit = range.location + range.length; 
    for(NSUInteger i = start; i < upper_limit; i += 2){ 
     [s addIndex:i]; 
    } 

    return s; 
} 

+ (id) WSS_indexSetWithEvenIndexesInRange: (NSRange)range 
{ 
    NSMutableIndexSet * s = [NSMutableIndexSet indexSet]; 

    // If the start of the range is odd, start with the next number. 
    NSUInteger start = range.location % 2 ? range.location + 1 : range.location; 
    NSUInteger upper_limit = range.location + range.length; 
    for(NSUInteger i = start; i < upper_limit; i += 2){ 
     [s addIndex:i]; 
    } 

    return s; 
} 

@end 

在一名助手功能:

NSRange rangeOfNumbers(NSUInteger start, NSUInteger end) 
{ 
    return (NSRange){start, end-start}; 
} 

所以,你可以這樣做:

NSIndexSet * s = [NSIndexSet WSS_indexSetWithEvenIndexesInRange:rangeOfNumbers(0, 10)]; 
NSLog(@"%@", s); 
// Prints: <NSMutableIndexSet: 0x7fccca4142a0>[number of indexes: 5 (in 5 ranges), indexes: (0 2 4 6 8)] 
+0

我就是這樣做的,但它並沒有回答這個問題:「我想知道是否有更簡潔的方法或任何內置的NSDictionary方法,我錯過了?」。 –

+0

謝謝,我後來認識到,@RamyAlZuhouri和我已經擴展到更直接地解決這一問題。 –

+0

但它仍然是恕我直言+1的最佳答案。 –

3

NSDictionary中沒有內置方法,它從數組中獲取替代值並將其分解爲2個集合,一個用於鍵值,另一個用於值。

你必須做這樣的事情:(這不是編譯器進行測試,但會給你一個想法。)

如果你想key = 1object = one

for(int i=0;i<keysAndValues.count;i+=2){ 
    [dict setObject:[keysAndValues objectAtIndex:i+1] forKey:[keysAndValues objectAtIndex:i]]; 
} 
+3

你有鍵和值向後。該值在'i + 1',關鍵在'i'。 – rmaddy

+0

我認爲它應該是這樣,或者我應該更新? –

+0

如果是這樣,你可以使用'dictionaryWithObjectsAndKeys'。以上代碼僅適用於OP中的這個特定示例。所以最好自己糾正答案。 – iDev

1

我有代碼循環訪問數組並提取鍵/值,但我是w如果有更清晰的方法或任何內置的NSDictionary方法,我會失蹤?

沒有出路,你必須迭代所有的數組。

如果您正在尋找一種更清潔的方式可能Josh Caswell的答案是最好的答案,但你仍然需要遍歷數組。

這將是很容易做到用這個方法:

+ (id)dictionaryWithObjectsAndKeys:(id)firstObject , ... 

但遺憾的是沒有一個直接的方法來創建從一個數組的va_list。另請參閱this question