iOS 随机打乱数组

有些情况下需要打乱一个数组的顺序,比如牌类游戏的洗牌。

如果是 Java 服务器,Java SDK 提供了一个 randomArray 的 API。但 iOS 并没有提供,Let's DIY。

主要思想是利用 iOS 提供的排序函数 sortUsingComparator: ,正常情况下的比较会返回 NSOrderedAscending = -1L, NSOrderedSame, NSOrderedDescending,对应的整形值分别是 -1, 0, 1,如果我们随机返回这三个数呢?


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;

}];

这么做会不会有什么风险呢?比如在排序过程中,进行了校验,如果进行了校验,肯定是通不过,有可能导致死循环。

所以我们加上两个输出,来验证一下结果,并顺便一探 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 输出的前一段信息去掉了,输出结果为:


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

)

第二次运行结果为:


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

)

可以看出是随机排了序,并没有引起死循环或者其他问题。

那么使用的排序方式是哪一种呢?

尽管最后结尾的比较顺序不尽相同,但从前面几次还说可以看出一些端倪,首先是前4个进行比较,然后说后5个进行比较,所以应该是二分排序?

然而并不是,如果我们在排序过程中,输出这个数组,你会发现这个数组在排序过程中并没有发生变化。

或者找一个简单的无序数组,然后按正常的方式输出 obj1 obj2 以及正确的比较结果,然后手动跟着一步一步的排序,你会发现,按照这些根本没用办法正确排序。

所以我推测,在排序时,有另外的一个数据区,这个排序先通过比较取得相关的信息,并将信息存入这个数据区,最后根据信息来调整顺序。

如果你知道,欢迎在评论区回复。

Github

我封装了 OC 版本和 Swift 版本的随机数组分类

RandomArray_Swift

RandomArray_OC

如果你有更好的建议,欢迎在评论区回复。

你可能感兴趣的:(iOS 随机打乱数组)