改组NSMutableArray的最佳方法是什么?

时间:2020-03-05 18:51:28  来源:igfitidea点击:

如果我们有一个" NSMutableArray",我们如何随机地随机播放这些元素?

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

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

解决方案

回答

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

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

编辑:由于格雷戈里·戈尔佐夫的回答以及miho和blahdiblah的评论,将((arc4random()%nElements)改为arc4random_uniform(nElements)`

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

编辑:添加了检查数组不为空,这要感谢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

回答

我们不需要swapObjectAtIndex方法。 exchangeObjectAtIndex:withObjectAtIndex:已经存在。

回答

这是改组NSArrays或者NSMutableArrays的最简单,最快的方法
(对象拼图是一个NSMutableArray,它包含拼图对象。我已经添加到
拼图对象变量索引,指示数组中的初始位置)

int randomSort(id obj1, id obj2, void *context ) {
        // returns random number -1 0 1
    return (random()%3 - 1);    
}

- (void)shuffle {
        // call custom sort function
    [puzzles sortUsingFunction:randomSort context:nil];

    // show in log how is our array sorted
        int i = 0;
    for (Puzzle * puzzle in puzzles) {
        NSLog(@" #%d has index %d", i, puzzle.index);
        i++;
    }
}

日志输出:

#0 has index #6
 #1 has index #3
 #2 has index #9
 #3 has index #15
 #4 has index #8
 #5 has index #0
 #6 has index #1
 #7 has index #4
 #8 has index #7
 #9 has index #12
 #10 has index #14
 #11 has index #16
 #12 has index #17
 #13 has index #10
 #14 has index #11
 #15 has index #13
 #16 has index #5
 #17 has index #2

我们也可以将obj1与obj2进行比较,并确定要返回的内容
可能的值为:

  • NSOrderedAscending = -1
  • NSOrderedSame = 0
  • NSOrderedDescending = 1