2011-09-26 19 views
0

我有一個可變詞典,它允許人們選擇星期幾。一旦選擇了一天,狀態就會使用numberWithBool進行更新。從可變詞典中提取特定數據

當我的NSLog它看起來像這樣的輸出:

{ 
    day = Monday; 
    isSelected = 1; 
}, 
    { 
    day = Tuesday; 
    isSelected = 0; 
}, 
    { 
    day = Wednesday; 
    isSelected = 0; 
}, 
    { 
    day = Thursday; 
    isSelected = 0; 
}, 
    { 
    day = Friday; 
    isSelected = 0; 
}, 
    { 
    day = Saturday; 
    isSelected = 0; 
}, 
    { 
    day = Sunday; 
    isSelected = 1; 
} 

我希望能夠提取所選擇的天,產生一個字符串的形式輸出。所以在這個例子中,輸出將是:週一,週日

我該怎麼做?

我創建的字典代碼如下:

NSMutableArray * tempSource = [[NSMutableArray alloc] init]; 
NSArray *daysOfWeek = [NSArray arrayWithObjects:@"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday", @"Sunday",nil]; 
for (int i = 0; i < 7; i++) 
{ 
    NSString *dayOfWeek = [daysOfWeek objectAtIndex:i]; 
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:dayOfWeek, @"day", [NSNumber numberWithBool:NO], @"isSelected",nil]; 
    [tempSource addObject:dict]; 
} 

[self setSourceArray:tempSource]; 
[tempSource release]; 

回答

3

您可以循環通陣列中所有的項目,並建立一個側陣列只含當天(1)名稱,或者您也可以使用謂詞,然後使用KVC直接提取日期(2)。

然後將過濾數組的組件加入到字符串中。

解決方案1:

NSMutableArray selectedDays = [[NSMutableArray alloc] init]; 
for(NSDictionary* entry in sourceArray) 
{ 
    if (([entry objectForKey:@"isSelected"] boolValue]) { 
     [selectedDays addObject:[entry objectForKey:@"day"]]; 
    } 
} 
NSString days = [selectedDays componentsJoinedByString:@", "]; 
[selectedDays release]; 

解決方案2:

NSPredicate* filter = [NSPredicate predicateWithFormat:@"SELF.isSelected == 1"]; // not sure about the exact format (no mac here to test right now so you may adapt a bit if it does not work directly) 
// get the array of dictionaries but only the ones that have isSelected==1 
NSArray selectedEntries = [sourceArray filteredArrayUsingPredicate:filter]; 
NSArray selectedDays = [selectedEntries valueForKey:@"day"]; // extract the "days" keys of the dictionaries. We have a NSArray of strings then. 
NSString days = [selectedDays componentsJoinedByString:@", "]; 

作爲一個側面說明,你這樣做的方式是很奇怪的。爲什麼有NSArray的NSDictionaries呢?由於這是簡單的,而且只包含BOOL的靜態大小的數組,所以您可以改爲使用C數組BOOL selected[7],而不是其他的。

然後有平日的名字,你應該使用的方法NSCalendar/NSDateFormatter/NSDateComponents(用正確的語言的用戶/區域設置自動),以獲得平日的標準名稱:使用創建一個NSDate一個NSDateComponent,您只需定義weekday組件,然後使用NSDateFormatter將其轉換爲字符串,然後選擇僅顯示星期幾名稱的字符串格式。


-(void)tableView:(UITableView*)tv didSelectRowAtIndexPath:(NSIndexPath*)indexPath { 
    // selectedDays is an instance variable in .h declared as 
    // BOOL selectedDays[7]; 
    selectedDays[indexPath.row] = ! selectedDays[indexPath.row]; 
    [tv reloadData]; 
} 

-(UITableViewCell*)tableView:(UITableView*)tv cellForRowAtIndexPath:(NSIndexPath*)indexPath { 
    static NSString* kCellIdentifier = @"DayCell"; 
    UITableViewCell* cell = [tv dequeueReusableCellWithIdentifier:kCellIdentifier]; 
    if (!cell) { 
    cell = [[[UITableViewCell alloc] initWithStyle:... identifier:kCellIdentifier]; autorelease]; 
    // configure here every property that is common to all for your cells (text color, etc) 
    } 

    // configure here things that will change from cell to cell 
    cell.accessoryType = selectedDays[indexPath.row] ? UITableViewCellAccessoryTypeCheckmarck : UITableViewCellAccessoryTypeNone; 
    cell.textLabel.text = weekdayName(indexPath.row); 

    return cell; 
} 

// Simple C function to return the name of a given weekday 
NSString* weekdayName(int weekday) 
{ 
#if WAY_1 
    /**** Solution 1 ****/ 
    // Optimization note: You may compute this once for all instead of recomputing it each time 
    NSDateComponents* comp = [[[NSDateComponents alloc] init] autorelease]; 
    [comp setWeekday:weekday+1]; // weekdays start at 1 for NSDateComponents 
    NSDate* d = [[NSCalendar currentCalendar] dateFromComponents:comp]; 

    NSDateFormatter* df = [[[NSDateFormatter alloc] init] autorelease]; 
    [df setDateFormat:@"EEEE"]; // format for the weekday 
    return [[df stringFromDate:d] capitalizedString]; 
#else 
    /**** Solution 2 ****/ 
    NSDateFormatter* df = [[[NSDateFormatter alloc] init] autorelease]; 
    NSArray* weekdayNames = [df weekdaySymbols]; // or maybe one of its sibling methods? check what is returned here to be sure 
    return [weekdayNames objectAtIndex:weekday]; 
#endif 
} 
+0

感謝您的快速反應,我用解決方案2和它工作完美。此代碼用於跟蹤哪些選擇在表格視圖上旁邊有複選標記。我對iphone編程頗爲陌生,並被告知使用NSDirearies的NSArray是一種很好的方法。我可以看到使用NSDateComponents獲得標準名稱的好處,並且肯定會研究這一點。 – AndyC

+0

實際上,通常一個對象的NSArray是管理對象然後在UITableView中顯示的好方法。如果objets的數量(= tableview中的行數)是動態的/非常量的,那麼使用NSDictionary的NSArray可能是一個好的解決方案。 **但是**通過'NSArray'方法('objetAtIndex' /'setObject:atIndex:')** AND **通過將'BOOL'值嵌入到'NSNumber'中非常痛苦和**,因爲您擁有常量單元數/天**(總是7)可能更容易操作C數組BOOL selected [7]而不是'NSNumber'的NSArray'嵌入'BOOL'。 – AliSoftware

+0

感謝您的建議,您的意見是有道理的,我一定會按照您的建議來看待它 – AndyC

0

是否有您避免NSMutableIndexSet理由嗎?

它可以簡化您的代碼:

NSArray *daysOfWeek = ...; 
NSMutableIndexSet *indexesOfSelectedDays = ...; 
NSArray *selectedDays = [daysOfWeek objectsAtIndexes:indexesOfSelectedDays]; 
0

使用NSPredicate創建選擇數組,其中isSelected是真實的項目謂詞,並用它來使用NSArray的-filteredArrayUsingPredicate:方法濾鏡陣列。 (@Miraaj發佈使用謂詞的速度比我可以輸入它的一個很好的例子。)然後採取濾波陣列,並挑選出的日子裏,像這樣的:

NSArray *selectedItems = [sourceArray filteredArrayUsingPredicate:somePredicate]; 
NSArray *days = [selectedItems valueForKey:@"day"]; 
NSString *daysString = [days [email protected]", "];