1. 程式人生 > >【Demo】IOS中將物件陣列按照時間戳排序

【Demo】IOS中將物件陣列按照時間戳排序

將物件按照時間戳排序,這裡典型的一個例子是登入賬戶的排序:本地客戶端可能儲存了多個賬戶資訊,在登入視窗使用者可以選擇已經登陸過的賬戶直接登入,現在的需求是要時刻讓最近登陸過的賬戶排在前面,對於每個賬戶,每次登陸時都記錄下當前登陸的時間,時間是一個時間戳(從1970年到現在的秒數)。我們要做的是將時間戳排序,然後按照時間戳的順序將所有賬戶排序。當然這也適用於其他關於時間排序的問題。

實現思路和過程

  • 1.先將每個賬戶物件的時間戳變數(要足夠精確,採用long long int)取出來:一方面要將每個時間戳轉換成NSDate物件用於排序;另一方面要將每一個時間戳轉換成一個字串作為key和對應的賬戶物件放入字典中做成一個雜湊表,用於之後根據排序好的時間戳將賬戶物件陣列排序。

    排序過程需要一個數組用於時間排序的NSDate物件,一個字典作為存放‘時間戳-物件’的雜湊表:

    // 時間戳陣列(存放時間NSDate物件用於排序)
    NSMutableArray *timeArr = [[NSMutableArray alloc]init];
    // 時間戳-物件字典,將物件和其對應的時間戳字串存入字典(雜湊表)
    NSMutableDictionary *dateKeyArr = [[NSMutableDictionary alloc]init];

    // 時間戳取出,並格式化處理
    for(Account *acc in _accountArray) {
        // 1.時間戳轉成時間物件用於排序
NSDate *date = [NSDate dateWithTimeIntervalSince1970:acc.loginTime]; [timeArr addObject:date]; // 2.時間戳轉成時間戳字串作為key,製作雜湊表 NSNumber *dataNum = [NSNumber numberWithLongLong:acc.loginTime]; NSString *datekey = [dataNum stringValue]; [dateKeyArr setObject:acc forKey:datekey]; }
  • 2.將取出的NSDate物件陣列排序
    // 3.將時間NSDate陣列排序
    NSArray *orderedDateArray = [timeArr sortedArrayUsingComparator:^NSComparisonResult(NSDate *date1, NSDate *date2) {
        // 降序排序,最近的時間靠前
        return [date2 compare:date1];
    }];
  • 3.按照排序好的時間陣列,安排好的順序將物件從雜湊表一次取出得到排序好的物件陣列:
    // 根據排序好的時間陣列對號入座將物件按時間排序
    // 臨時陣列,儲存排序後的物件陣列
    NSMutableArray *sortedAccounts = [[NSMutableArray alloc]init];
    NSDate *datekey = [[NSDate alloc]init];
    for (int i = 0; i<orderedDateArray.count; i++) {
        datekey = orderedDateArray[i];
        // 日期物件轉換成時間戳字串key
        NSString *datekeys = [NSString stringWithFormat:@"%lld", (long long)[datekey timeIntervalSince1970]];
        // 根據時間戳字串key取對應的物件(雜湊表)
        [sortedAccounts addObject:[dateKeyArr objectForKey:datekeys]];
    }

    // sortedAccounts就是我們要的結果了

完整的示例Demo

這裡製作一個只包含使用者名稱和時間戳的假賬戶資料,排序後按照順序顯示在一個textview中:
這裡寫圖片描述

賬戶Account

//
//  Account.h
//  TimeSortDemo
//
//  Created by Xinhou Jiang on 22/12/16.
//  Copyright © 2016年 Xinhou Jiang. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Account : NSObject

@property (nonatomic, copy) NSString *name;              // 姓名
@property (nonatomic, assign) long long int loginTime;   // 上次登入時間戳(距離1970年的秒數)

+ (Account*)newAccountWithName:(NSString *)name andTime:(long long int)logintime;

@end
//
//  Account.m
//  TimeSortDemo
//
//  Created by Xinhou Jiang on 22/12/16.
//  Copyright © 2016年 Xinhou Jiang. All rights reserved.
//

#import "Account.h"

@implementation Account

+ (Account *)newAccountWithName:(NSString *)name andTime:(long long)logintime {
    Account *acc = [[Account alloc] init];
    acc.name = name;
    acc.loginTime = logintime;
    return acc;
}

@end

UIViewController

//
//  ViewController.m
//  TimeSortDemo
//
//  Created by Xinhou Jiang on 22/12/16.
//  Copyright © 2016年 Xinhou Jiang. All rights reserved.
//

#import "ViewController.h"
#import "Account.h"

@interface ViewController ()

@property(nonatomic, strong) IBOutlet UITextView *text;

@property (nonatomic, strong) NSMutableArray<Account*> *accountArray; // 賬戶陣列

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 請求資料
    [self request];
    // 排序前
    [self showUI];

}

- (void) request {
    // 初始化陣列並新增幾個賬戶假資料物件
    _accountArray = [[NSMutableArray alloc] init];
    [_accountArray addObject:[Account newAccountWithName:@"張三" andTime:1450675000]];
    [_accountArray addObject:[Account newAccountWithName:@"李四" andTime:1450923000]];
    [_accountArray addObject:[Account newAccountWithName:@"小明" andTime:1450656000]];
    [_accountArray addObject:[Account newAccountWithName:@"小麗" andTime:1450435000]];
}

// 將陣列按照時間戳排序
- (IBAction)sort:(id)sender {
    /** 按照時間戳排序 **/
    // 1.初始化
    // 時間戳陣列(存放時間NSDate物件用於排序)
    NSMutableArray *timeArr = [[NSMutableArray alloc]init];
    // 時間戳-物件字典,將物件和其對應的時間戳字串存入字典(雜湊表)
    NSMutableDictionary *dateKeyArr = [[NSMutableDictionary alloc]init];

    // 2.時間戳取出,並格式化處理
    for(Account *acc in _accountArray) {
        // 時間戳轉成時間物件用於排序
        NSDate  *date = [NSDate dateWithTimeIntervalSince1970:acc.loginTime];
        [timeArr addObject:date];
        // 時間戳轉成時間戳字串作為key,製作雜湊表
        NSNumber *dataNum = [NSNumber numberWithLongLong:acc.loginTime];
        NSString *datekey = [dataNum stringValue];
        [dateKeyArr setObject:acc forKey:datekey];
    }

    // 3.將時間NSDate陣列排序
    NSArray *orderedDateArray = [timeArr sortedArrayUsingComparator:^NSComparisonResult(NSDate *date1, NSDate *date2) {
        // 降序排序,最近的時間靠前
        return [date2 compare:date1];
    }];

    // 4.根據排序好的時間陣列對號入座將物件按時間排序
    // 臨時陣列,儲存排序後的物件陣列
    NSMutableArray *sortedAccounts = [[NSMutableArray alloc]init];
    NSDate *datekey = [[NSDate alloc]init];
    for (int i = 0; i<orderedDateArray.count; i++) {
        datekey = orderedDateArray[i];
        // 日期物件轉換成時間戳字串key
        NSString *datekeys = [NSString stringWithFormat:@"%lld", (long long)[datekey timeIntervalSince1970]];
        // 根據時間戳字串key取對應的物件(雜湊表)
        [sortedAccounts addObject:[dateKeyArr objectForKey:datekeys]];
    }

    // 5.更新排序後的物件陣列[ARC中不需要手動釋放排序前的陣列]
    _accountArray = sortedAccounts;

    // 顯示排序後的資料
    [self showUI];
}

// 顯示資料到頁面
- (void) showUI {
    NSString *s = [NSString stringWithFormat:@"%@[%lld]\n%@[%lld]\n%@[%lld]\n%@[%lld]",
                   _accountArray[0].name,_accountArray[0].loginTime,
                   _accountArray[1].name,_accountArray[1].loginTime,
                   _accountArray[2].name,_accountArray[2].loginTime,
                   _accountArray[3].name,_accountArray[3].loginTime];
    _text.text = s;
}

@end

這裡寫圖片描述