有些情況下需要打亂一個(gè)數(shù)組的順序媚媒,比如牌類游戲的洗牌锄码。
如果是 Java 服務(wù)器,Java SDK 提供了一個(gè) randomArray 的 API咪鲜。但 iOS 并沒有提供饺蔑,Let's DIY。
主要思想是利用 iOS 提供的排序函數(shù) sortUsingComparator:
嗜诀,正常情況下的比較會(huì)返回 NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending
猾警,對(duì)應(yīng)的整形值分別是 -1, 0, 1,如果我們隨機(jī)返回這三個(gè)數(shù)呢隆敢?
NSMutableArray *array = [@[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9"] mutableCopy];
[array sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return (NSInteger)arc4random() % 3 - 1;
}];
這么做會(huì)不會(huì)有什么風(fēng)險(xiǎn)呢发皿?比如在排序過程中,進(jìn)行了校驗(yàn)拂蝎,如果進(jìn)行了校驗(yàn)穴墅,肯定是通不過,有可能導(dǎo)致死循環(huán)温自。
所以我們加上兩個(gè)輸出玄货,來驗(yàn)證一下結(jié)果,并順便一探 iOS SDK 為我們提供的排序算法是哪一類悼泌。
NSMutableArray *array = [@[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8"] mutableCopy];
NSLog(@"%@, %p", array, array);
[array sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSInteger randomResult = (NSInteger)arc4random() % 3 - 1;
NSLog(@"%@, %@, %@", obj1, obj2, @(randomResult));
return randomResult;
}];
NSLog(@"%@, %p", array, array);
為了方便查看松捉,我將 NSLog 輸出的前一段信息去掉了,輸出結(jié)果為:
1, 2
3, 4
2, 3
2, 4
5, 6
7, 8
7, 9
5, 8
6, 8
6, 7
3, 5
3, 8
4, 8
4, 6
4, 7
2, 7
2, 9
1, 9
(
5,
3,
8,
6,
4,
7,
2,
9,
1
)
第二次運(yùn)行結(jié)果為:
1, 2
3, 4
2, 4
1, 4
1, 3
5, 6
7, 8
8, 9
7, 9
6, 7
6, 9
6, 8
5, 8
2, 7
2, 9
2, 6
2, 8
4, 8
4, 5
(
7,
9,
6,
2,
8,
5,
4,
1,
3
)
可以看出是隨機(jī)排了序馆里,并沒有引起死循環(huán)或者其他問題隘世。
那么使用的排序方式是哪一種呢可柿?
盡管最后結(jié)尾的比較順序不盡相同,但從前面幾次還說可以看出一些端倪丙者,首先是前4個(gè)進(jìn)行比較复斥,然后說后5個(gè)進(jìn)行比較,所以應(yīng)該是二分排序械媒?
然而并不是目锭,如果我們?cè)谂判蜻^程中,輸出這個(gè)數(shù)組纷捞,你會(huì)發(fā)現(xiàn)這個(gè)數(shù)組在排序過程中并沒有發(fā)生變化侣集。
或者找一個(gè)簡單的無序數(shù)組,然后按正常的方式輸出 obj1 obj2 以及正確的比較結(jié)果兰绣,然后手動(dòng)跟著一步一步的排序世分,你會(huì)發(fā)現(xiàn),按照這些根本沒用辦法正確排序缀辩。
所以我推測(cè)臭埋,在排序時(shí),有另外的一個(gè)數(shù)據(jù)區(qū)臀玄,這個(gè)排序先通過比較取得相關(guān)的信息瓢阴,并將信息存入這個(gè)數(shù)據(jù)區(qū),最后根據(jù)信息來調(diào)整順序健无。
如果你知道荣恐,歡迎在評(píng)論區(qū)回復(fù)。
Github
我封裝了 OC 版本和 Swift 版本的隨機(jī)數(shù)組分類
如果你有更好的建議累贤,歡迎在評(píng)論區(qū)回復(fù)叠穆。