什么是最好的方式来洗牌NSMutableArray?

如果你有一个NSMutableArray ,你是如何随机地随机洗牌的?

(我有我自己的答案,这是张贴在下面,但我是Cocoa新手,我很想知道是否有更好的方法。)


更新:正如@Mukesh所指出的那样,从iOS 10+和m​​acOS 10.12+开始,有一个可用于-[NSMutableArray shuffledArray]-[NSMutableArray shuffledArray]方法。 有关详细信息,请参阅https://developer.apple.com/documentation/foundation/nsarray/1640855-shuffledarray?language=objc。 (但请注意,这会创建一个新的数组,而不是将这些元素移动到位。)


您不需要swapObjectAtIndex方法。 exchangeObjectAtIndex:withObjectAtIndex:已存在。


我通过向NSMutableArray添加一个类来解决这个问题。

编辑:删除不必要的方法感谢拉德的回答。

编辑:更改(arc4random() % nElements)arc4random_uniform(nElements)感谢格雷戈里Goltsov的答复和评论miho和blahdiblah

编辑:罗恩改进,感谢评论

编辑:添加检查数组不是空的,由于评论由Mahesh Agrawal

//  NSMutableArray_Shuffling.h

#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#else
#include <Cocoa/Cocoa.h>
#endif

// This category enhances NSMutableArray by providing
// methods to randomly shuffle the elements.
@interface NSMutableArray (Shuffling)
- (void)shuffle;
@end


//  NSMutableArray_Shuffling.m

#import "NSMutableArray_Shuffling.h"

@implementation NSMutableArray (Shuffling)

- (void)shuffle
{
    NSUInteger count = [self count];
    if (count <= 1) return;
    for (NSUInteger i = 0; i < count - 1; ++i) {
        NSInteger remainingCount = count - i;
        NSInteger exchangeIndex = i + arc4random_uniform((u_int32_t )remainingCount);
        [self exchangeObjectAtIndex:i withObjectAtIndex:exchangeIndex];
    }
}

@end

由于我还没有评论,我想我会提供一个完整的答复。 我以许多方式修改了Kristopher Johnson的项目实现(尽量使其尽可能简洁),其中之一是arc4random_uniform()因为它避免了模偏差。

// NSMutableArray+Shuffling.h
#import <Foundation/Foundation.h>

/** This category enhances NSMutableArray by providing methods to randomly
 * shuffle the elements using the Fisher-Yates algorithm.
 */
@interface NSMutableArray (Shuffling)
- (void)shuffle;
@end

// NSMutableArray+Shuffling.m
#import "NSMutableArray+Shuffling.h"

@implementation NSMutableArray (Shuffling)

- (void)shuffle
{
    NSUInteger count = [self count];
    for (uint i = 0; i < count - 1; ++i)
    {
        // Select a random element between i and end of array to swap with.
        int nElements = count - i;
        int n = arc4random_uniform(nElements) + i;
        [self exchangeObjectAtIndex:i withObjectAtIndex:n];
    }
}

@end
链接地址: http://www.djcxy.com/p/14915.html

上一篇: What's the Best Way to Shuffle an NSMutableArray?

下一篇: How safe is Internal Storage?