在面向iOS開發人員的採訪中,他們問我如何找到大型數組(> 100萬項)中刪除項目的最快解決方案,即:應用程序有從服務器的數組(我們不關心從服務器獲取此數組的方法)。然後,在服務器上,他們刪除了本地數組&中的幾個項目,我們不知道。那麼,我們如何才能在本地找到已刪除的項目,基於服務器&本地陣列上的新陣列? 我認爲在02天后&找到下面這個循環,但它只是當服務器刪除項目在開始或結束數組時。當在數組中間刪除項目時,此循環需要很長時間才能完成。iOS在大型數組中查找已刪除的項目(即:> 100萬項)
#define rchar (rand() % ('z'-'a') + 'a')
- (無效)viewDidLoad中:
NSMutableArray * mar = [NSMutableArray new]; // represent server array.
for (int i = 0; i<50000; i++) //10 50000 200000 400000 600000 800000
{
NSString * str = [NSString stringWithFormat:@"%c%c%c%c",rchar, rchar, rchar, rchar];
[mar addObject:str];
}
NSMutableArray *tmpServerArr = [[NSMutableArray alloc] initWithArray:mar copyItems:YES];
NSMutableArray *localArr = [[NSMutableArray alloc]initWithCapacity:50002]; // represent local array
for (int i = 0; i<50002; i++) //10 50000 200000
{
switch (i) {
case 32111: [localArr addObject:[NSString stringWithFormat:@"%c%c%c%c",rchar, rchar, rchar, rchar]];
break;
case 41234: [localArr addObject:[NSString stringWithFormat:@"%c%c%c%c",rchar, rchar, rchar, rchar]];
break;
case 50000: [localArr addObject:mar[32111]];
break;
case 50001: [localArr addObject:mar[41234]];
break;
default: [localArr addObject:mar[i]];
break;
}
}
NSUInteger localremainItem = [localArr count];
NSDate *start;
NSUInteger loopWhile = 0;
while (localremainItem > 0) {
// while ([localArr count] > 0) {
NSUInteger idxItemStr = (localremainItem -1 - pow(-1, loopWhile)*(localremainItem-1))/2; // -1;
NSLog(@"idxstring: %li -- pow: %f", idxItemStr, pow(-1, loopWhile));
NSString *itemStr = localArr[idxItemStr];
NSLog(@"item checked : %@]", itemStr);
NSPredicate *pre = [ NSPredicate predicateWithFormat:@"NOT (SELF like %@)", itemStr];
NSCountedSet * localCountedSet = [[ NSCountedSet alloc] initWithArray:localArr];
NSCountedSet * serverCountedSet = [[ NSCountedSet alloc] initWithArray:tmpServerArr];
if ([localCountedSet countForObject:itemStr] > [serverCountedSet countForObject:itemStr]) {
NSLog(@"this item %@ was deleted in server.", itemStr);
}
//else {
[localArr filterUsingPredicate: pre];
[tmpServerArr filterUsingPredicate:pre];
NSLog(@"localremain: %li", [localArr count]);
NSLog(@"tmpserverremain: %li", [tmpServerArr count]);
// }
if ([localArr count] == [tmpServerArr count]) {
localremainItem = 0;
}
else localremainItem = [localArr count];
loopWhile +=1;
}
NSLog(@"now server arr is controled! time: %f", -[start timeIntervalSinceNow]);
謝謝您的幫助。
**更新2015年11月14日:這個循環以下是8倍的速度:
在viewDidLoad中:
while ([localArr count] >0) {
NSUInteger maxRange =0;
if ([localArr count] >500) {
maxRange = 500;
}else maxRange = [localArr count];
NSArray *sampleTest = [[NSArray alloc] initWithArray:[localArr subarrayWithRange:NSMakeRange(0,maxRange)]];
NSLog(@"sampleTest cnt: %lu", (unsigned long)[sampleTest count]);
if ([self countSampleTest:localArr serverArr:tmpServerArr sampleTest:sampleTest]) {
NSPredicate *pre = [ NSPredicate predicateWithFormat:@"NOT (SELF in %@)", sampleTest];
[localArr filterUsingPredicate: pre];
[tmpServerArr filterUsingPredicate:pre];
NSLog(@"localremain: %li", [localArr count]);
NSLog(@"tmpserverremain: %li", [tmpServerArr count]);
}
else {
NSLog(@"deleted item in here!: %i, %li", 0, [sampleTest count]); //[localArr count]/10);
int found = 0;
while (found <10) {
maxRange =0;
if ([localArr count] >50) {
maxRange = 50;
}else maxRange = [localArr count];
NSArray *sampleTest1 = [[NSArray alloc] initWithArray:[localArr subarrayWithRange:NSMakeRange(0,maxRange)]];
NSLog(@"sampleTest1 cnt: %lu", (unsigned long)[sampleTest1 count]);
if ([self countSampleTest:localArr serverArr:tmpServerArr sampleTest:sampleTest1]) {
NSPredicate *pre = [ NSPredicate predicateWithFormat:@"NOT (SELF in %@)", sampleTest1];
[localArr filterUsingPredicate: pre];
[tmpServerArr filterUsingPredicate:pre];
NSLog(@"localremain: %li", [localArr count]);
NSLog(@"tmpserverremain: %li", [tmpServerArr count]);
}
else {
NSUInteger k = 0;
while (k< [sampleTest1 count]) {
NSLog(@"item checked %lu : %@]", (unsigned long)k, sampleTest1[k]);
NSCountedSet * localCountedSet = [[ NSCountedSet alloc] initWithArray:localArr];
NSCountedSet * serverCountedSet = [[ NSCountedSet alloc] initWithArray:tmpServerArr];
if ([localCountedSet countForObject:sampleTest1[k]] > [serverCountedSet countForObject:sampleTest1[k]]) {
NSLog(@"this item %@ was deleted in server.", sampleTest1[k]);
}
NSPredicate *pre = [ NSPredicate predicateWithFormat:@"NOT (SELF like %@)", sampleTest1[k]];
[localArr filterUsingPredicate: pre];
[tmpServerArr filterUsingPredicate:pre];
NSLog(@"localremain: %li", [localArr count]);
NSLog(@"tmpserverremain: %li", [tmpServerArr count]);
if ([localArr count] == [tmpServerArr count]) {
k = [sampleTest1 count];
found = 10;
}else k +=1;
}
}
found +=1;
}
}
if ([localArr count] == [tmpServerArr count]) {
localArr = nil;
}
// if ([sampleTest count] == 0) {
// localArr = nil;
// }
}
NSLog(@"this stuck is done!");//end viewDidLoad.
-(BOOL)countSampleTest: (NSMutableArray *)localArr serverArr:(NSMutableArray *)tmpServerArr sampleTest:(NSArray *)sampleTest{
BOOL tf;
int cntSampleLoc = 0;
int cntSampleServer = 0;
for (int i = 0 ; i < [sampleTest count]; i++) {
NSCountedSet * localCountedSet = [[ NSCountedSet alloc] initWithArray:localArr];
NSCountedSet * serverCountedSet = [[ NSCountedSet alloc] initWithArray:tmpServerArr];
cntSampleLoc += [localCountedSet countForObject:sampleTest[i]];
//if (localArr[i] in tmpServerArr) {
cntSampleServer +=[serverCountedSet countForObject:sampleTest[i]];
// }
}
if (cntSampleServer == cntSampleLoc) {
tf= true;
}else tf = false;
return tf;}
個人而言,我會告訴他們這是一個可怕的實現:)這似乎好得多沿增量比通整個數組或搜索數組。 –
@MikeM:他們是老闆,我不能那樣告訴他們。多謝。 – Nik
@Nik,你肯定*可以*和*應該*告訴別人,如果你可以備份它,實施是不好的,提供一個更好的選擇,並以專業的方式呈現你的發現。沒有人喜歡被告知他們錯了,但我相信很多人會喜歡有最好的工具。 –