算法討論:獲取上個(gè)月第一天到今天的信息

需求

這兩個(gè)獲取一個(gè)需求,需要做一個(gè)打卡列表,顯示上個(gè)月所有打卡的信息,及這個(gè)月到今天的的打卡信息,并且標(biāo)注出來(lái)月份。設(shè)計(jì)界面大致如此:

需求圖片

后臺(tái)接口只能返回已經(jīng)打卡的信息。如果當(dāng)天沒(méi)有打卡,是不返回的。

//接口返回?cái)?shù)據(jù)結(jié)構(gòu)
"data": [
        {
            "signLastTime": 1522199821084,                 //當(dāng)天最后一次打卡時(shí)間
            "signMonth": 3,                                 //當(dāng)天屬于幾月
            "week": "周三",                                 //當(dāng)天屬于周幾
            "inDate": 1522199817934,                       //數(shù)據(jù)庫(kù)返回時(shí)間,本地?zé)o用
            "signDay": 28,                                 //當(dāng)天屬于幾號(hào)
            "signItems": [                                 //當(dāng)天打卡次數(shù),返回每次打卡數(shù)據(jù)
                {
                    "longitude": 123566,          //經(jīng)度
                    "signAdress": "北京市海淀區(qū)上地地鐵口",   //地址
                    "signTime": 1522199817934,        //打卡時(shí)間
                    "latitude": 456233           //緯度
                },
                {
                    "longitude": 456233,
                    "signAdress": "北京市海淀區(qū)西直門(mén)地鐵口",
                    "signTime": 1522199821084,
                    "latitude": 123566
                }
            ],
            "reDate": 1522199821084,      //數(shù)據(jù)庫(kù)返回時(shí)間,無(wú)用
            "signYear": 2018,                      //本次打卡數(shù)據(jù)年份
            "id": "5abaed0923130b394c1e10ce",      //id
            "signFirstTime": 1522199817934,            //當(dāng)天首次打卡時(shí)間
            "userId": 111225,                   //打卡人id
            "status": 1                             //客戶(hù)端無(wú)用
        }

大家可以先不看我的解決方法,自己思考一下如何來(lái)寫(xiě)這個(gè)算法,才能達(dá)到最優(yōu)。


我的解決方案

聲明一下,我的解決方案可能不是最優(yōu)的,如果有好的想法,我們?cè)诹粞钥梢砸黄鹩懻摗?/p>

  1. 按照后臺(tái)接口返回,創(chuàng)建model類(lèi)。
  2. 創(chuàng)建一個(gè)config類(lèi),通過(guò)后臺(tái)返回?cái)?shù)據(jù),返回能被tableView解析顯示的數(shù)據(jù)。

config作為配置類(lèi),所有的算法配置寫(xiě)在這個(gè)類(lèi)中。類(lèi)大概是

思路:
  1. 通過(guò)獲取當(dāng)月到今天的天數(shù) currentMonthDay,在獲取上個(gè)月總天數(shù)lastMonthDay。
  2. 使用for循環(huán)來(lái)循環(huán),次數(shù) = currentMonthDay + lastMonthDay, 來(lái)生成一個(gè)只包含'yyyy-MM-dd'字符串類(lèi)型的數(shù)組【數(shù)組A】,生成一個(gè)字典包含key: 是上面的字符串,value:model的類(lèi)【字典A】
  3. 使用for循環(huán), 次數(shù) = punchList.count ,已經(jīng)打卡的天數(shù)。再通過(guò)打卡時(shí)某一天,替換上面字典A中的value:model值。
  4. 通過(guò)for循環(huán)【數(shù)組A】,來(lái)獲取【字典A】中的model值,生成一個(gè)新的數(shù)組【數(shù)組B】。使用這一步主要是確保時(shí)間的順序。
  5. 返回【數(shù)組B】就是需要的這兩個(gè)月的打卡數(shù)據(jù)model數(shù)組
    6 通過(guò)在index = 0處插入當(dāng)月的月份,在 index = currentMonthDay +1 處插入上個(gè)月的月份。就生成了需要的結(jié)果。

結(jié)果類(lèi)型

{
    monthStr = 4;
},
<NTOutdoorPunchInfoModel: 0x10eb40830>,
<NTOutdoorPunchInfoModel: 0x10eb3f6b0>,
<NTOutdoorPunchInfoModel: 0x10eb1da40>,
{
    monthStr = 3;
},
<NTOutdoorPunchInfoModel: 0x10ec4e810>,
<NTOutdoorPunchInfoModel: 0x10ec1dc40>,
<NTOutdoorPunchInfoModel: 0x108896f00>,
......

上代碼
//config.m
@property (nonatomic, strong)NSMutableDictionary *monthDicInfo;

//public 對(duì)外放開(kāi)接口的類(lèi),主要是來(lái)配置解析數(shù)據(jù)的方法
- (NSArray *)configForPunchList:(NSArray *)punchList {
    // 1. 首先創(chuàng)建返回解析好的數(shù)組,作為返回值返回
   NSMutableArray *monthInfo = [[NSMutableArray alloc] init];
   //2. 調(diào)用getMonthList 來(lái)獲取一個(gè)數(shù)組(備注1)和一個(gè)字典(備注2)
   NSArray *monthList = [self getMonthList];
  //3.  for 循環(huán) 服務(wù)器返回的數(shù)據(jù),來(lái)更
for (NSDictionary *dic in punchList) {
        NTOutdoorPunchInfoModel *model = [NTOutdoorPunchInfoModel getModelFromDic:dic];
        NSTimeInterval firstTimePunch = model.signFirstTime;
        NSString *timeStr = [TimeUtil getDateStr:firstTimePunch/1000];
        [self.monthDicInfo setValue:model forKey:timeStr];
    }

    //4. 確定今天是幾月,通過(guò)今天是幾月,得出上個(gè)月是幾月,設(shè)置保存上個(gè)月的一個(gè)字典
    NSInteger nowMonthInt = [self getYearOrMonthOrDayForDate:[NSDate date] calendarUnit:NSCalendarUnitMonth];
    NSInteger lastMonthInt = (nowMonthInt == 1) ? 12 : nowMonthInt -1;
    NSDictionary *nowMonthDic = @{@"monthStr":[NSString stringWithFormat:@"%ld",(long)nowMonthInt]};
    NSDictionary *lastMonthDic = @{@"monthStr":[NSString stringWithFormat:@"%ld",(long)lastMonthInt]};
   [monthInfo addObject:nowMonthDic];
// 5. for循環(huán)備注1的數(shù)組,通過(guò)key值,順序獲取備注2中的model值,保存到monthInfoList
 for (NSString *timeStr in monthList) {
        NTOutdoorPunchInfoModel *model = [self.monthDicInfo objectForKey:timeStr];
        [monthInfo addObject:model];
    }
   //6. 確定幾天是幾號(hào),在monthInfoList插入到index = nowDay + 1數(shù)組中去
 NSInteger nowDay = [self getYearOrMonthOrDayForDate:[NSDate date] calendarUnit:NSCalendarUnitDay];
    [monthInfo insertObject:lastMonthDic atIndex:nowDay + 1];
    return monthInfo;
  //7. 返回配置好的 
   return   monthInfoList
}

//private
//返回一個(gè)字符串?dāng)?shù)組,數(shù)組包括從當(dāng)天開(kāi)始到上個(gè)月1號(hào)的日期,格式y(tǒng)yyy-MM-dd
//并且創(chuàng)建了一個(gè)字典,key是yyyy-MM-dd的日期字符串,value是model類(lèi)
- (NSMutableArray *)getMonthList { 
    NSMutableArray *monthList = [[NSMutableArray alloc] init];
    
    NSDate *currentDate = [NSDate date];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *lastMonthComps = [[NSDateComponents alloc] init];
    //當(dāng)月現(xiàn)在是幾日
    NSInteger nowDay = [self getYearOrMonthOrDayForDate:[NSDate date] calendarUnit:NSCalendarUnitDay];
    NSInteger lastMonthDays = [self getDaysWithLastMonth];
    int count = 0;
    for (NSInteger i = nowDay+lastMonthDays; i > 0; i --) {
        //    [lastMonthComps setYear:1]; // year = 1表示1年后的時(shí)間 year = -1為1年前的日期,month day 類(lèi)推
        [lastMonthComps setDay:-count];
        NSDate *newdate = [calendar dateByAddingComponents:lastMonthComps toDate:currentDate options:0];
        NSString *dateStr = [formatter stringFromDate:newdate];
        [monthList addObject:dateStr];
        
        //保存每個(gè)model
        NTOutdoorPunchInfoModel *model = [[NTOutdoorPunchInfoModel alloc] init];
        model.signYear = [NSString stringWithFormat:@"%ld",(long)[self getYearOrMonthOrDayForDate:newdate calendarUnit:NSCalendarUnitYear]];
        model.signMonth = [NSString stringWithFormat:@"%ld",(long)[self getYearOrMonthOrDayForDate:newdate calendarUnit:NSCalendarUnitMonth]];
        model.signDay = [NSString stringWithFormat:@"%ld",(long)[self getYearOrMonthOrDayForDate:newdate calendarUnit:NSCalendarUnitDay]];
        model.week = [self getWeekStrForDate:newdate];
        [self.monthDicInfo setValue:model forKey:dateStr];
        count++;
    }
    return monthList;
}

//private
//通過(guò)一個(gè)日期字符串返回date
- (NSDate *)getDateWithDateStr:(NSString *)str {}

//private
//獲取上個(gè)月有多少天
- (NSInteger)getDaysWithLastMonth {}

//private
//根據(jù)date日期,和calendarUnit返回date屬于哪一年,月,日
- (NSInteger)getYearOrMonthOrDayForDate:(NSDate *)date calendarUnit:(NSCalendarUnit)unit {
}

//private
//根據(jù)date日期獲取是周幾,轉(zhuǎn)化為例如'星期天' 表達(dá)
- (NSString *)getWeekStrForDate:(NSDate *)date {}
結(jié)尾:

可以?xún)?yōu)化的地方:如果當(dāng)天多次進(jìn)入到這個(gè)頁(yè)面,可以把獲取的【數(shù)組A】【字典A】緩存一下,每次進(jìn)來(lái)查看【數(shù)組A】首條是否是當(dāng)天,如果是當(dāng)天直接使用,不用走第二步,節(jié)省點(diǎn)計(jì)算時(shí)間。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,535評(píng)論 19 139
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線(xiàn)程,因...
    小菜c閱讀 7,317評(píng)論 0 17
  • 那一年,我身上的毛還沒(méi)長(zhǎng)齊,一個(gè)星期只有一元零花錢(qián)。 那一年,父母還對(duì)我寄予厚望,班主任更是當(dāng)著全班的面夸我是班級(jí)...
    悶豆豆閱讀 395評(píng)論 0 0
  • 沒(méi)錯(cuò),我就是來(lái)虐狗的,汪~汪~ 昨天一直在刷著圈里,看的全都是林心如霍建華大婚的訊息。其實(shí)對(duì)于兩人的婚禮我是不太感...
    九九兒閱讀 299評(píng)論 0 1
  • 還記得那首不想長(zhǎng)大的歌嗎,當(dāng)時(shí)剛聽(tīng)的時(shí)候還小,一心想要長(zhǎng)大,覺(jué)得長(zhǎng)大了就自由了,可是隨著時(shí)間的流逝,才發(fā)現(xiàn)我們已經(jīng)...
    范二的南瓜菇?jīng)?/span>閱讀 947評(píng)論 0 1

友情鏈接更多精彩內(nèi)容