如果你有一个
(我有自己的答案,这是张贴在下面,但我是新的可可,我有兴趣知道是否有更好的方法。)
更新:正如@mukesh所指出的,从iOS 10+和MacOS 10.12+开始,有一个
我通过向nsmutablearray添加一个类别来解决这个问题。
编辑:删除了不必要的方法,感谢LADD的回答。
编辑:由于Gregory Goltsov的回答和Miho和Blahdiblah的评论,
编辑:循环改进,感谢Ron的评论
编辑:添加检查数组是否不为空,这要感谢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:已存在。
既然我还不能发表评论,我想我会给出一个完整的回应。我以多种方式修改了Kristopher Johnson对我的项目的实现(真的试图使其尽可能简洁),其中之一是
// 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
从iOS 10可以使用新的
https://developer.apple.com/reference/foundation/nsarray/1640855-无序播放
let shuffledArray = array.shuffled()
号
一个稍微改进和简洁的解决方案(与最重要的答案相比)。
该算法与文献中描述的"Fisher-Yates shuffle"相同。
在目标C中:
@implementation NSMutableArray (Shuffle)
// Fisher-Yates shuffle
- (void)shuffle
{
for (NSUInteger i = self.count; i > 1; i--)
[self exchangeObjectAtIndex:i - 1 withObjectAtIndex:arc4random_uniform((u_int32_t)i)];
}
@end
在Swift 3.2和4.x中:
extension Array {
/// Fisher-Yates shuffle
mutating func shuffle() {
for i in stride(from: count - 1, to: 0, by: -1) {
swapAt(i, Int(arc4random_uniform(UInt32(i + 1))))
}
}
}
。
在Swift 3.0和3.1中:
extension Array {
/// Fisher-Yates shuffle
mutating func shuffle() {
for i in stride(from: count - 1, to: 0, by: -1) {
let j = Int(arc4random_uniform(UInt32(i + 1)))
(self[i], self[j]) = (self[j], self[i])
}
}
}
号
注:使用
注:还提供了一种不稳定洗牌的算法(如果计数>1,则强制更改所有位置)。
这是最简单和最快的方法来洗牌NSarray或NSmutableArrays(对象拼图是一个非可变数组,它包含拼图对象。我已添加到指示数组中初始位置的益智对象变量索引) 短码网:DuanMa.NET
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进行比较,并决定要返回的内容可能的值是:
从iOS 10,您可以使用游戏工具包中的nsarray
import GameplayKit
extension Array {
@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
func shuffled() -> [Element] {
return (self as NSArray).shuffled() as! [Element]
}
@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
mutating func shuffle() {
replaceSubrange(0..<count, with: shuffled())
}
}
号
有一个很好的流行库,它有这个方法作为它的一部分,在GitHub中称为sstoolkit。文件nsmutablerray+sstoolkitadditions.h包含shuffle方法。你也可以用它。其中,似乎有很多有用的东西。
这个图书馆的主页在这里。
如果使用此代码,则代码如下:
#import <SSCategories.h>
NSMutableArray *tableData = [NSMutableArray arrayWithArray:[temp shuffledArray]];
。
这个图书馆也有一个豆荚(见椰子)
如果元素有重复。
例如阵列:A A A B或B B A A
唯一的解决办法是:A B A B A
- (void)shuffleSequenceSelected {
[sequenceSelected shuffle];
[self shuffleSequenceSelectedLoop];
}
- (void)shuffleSequenceSelectedLoop {
NSUInteger count = sequenceSelected.count;
for (NSUInteger i = 1; i < count-1; i++) {
// Select a random element between i and end of array to swap with.
NSInteger nElements = count - i;
NSInteger n;
if (i < count-2) { // i is between second and second last element
obj *A = [sequenceSelected objectAtIndex:i-1];
obj *B = [sequenceSelected objectAtIndex:i];
if (A == B) { // shuffle if current & previous same
do {
n = arc4random_uniform(nElements) + i;
B = [sequenceSelected objectAtIndex:n];
} while (A == B);
[sequenceSelected exchangeObjectAtIndex:i withObjectAtIndex:n];
}
} else if (i == count-2) { // second last value to be shuffled with last value
obj *A = [sequenceSelected objectAtIndex:i-1];// previous value
obj *B = [sequenceSelected objectAtIndex:i]; // second last value
obj *C = [sequenceSelected lastObject]; // last value
if (A == B && B == C) {
//reshufle
sequenceSelected = [[[sequenceSelected reverseObjectEnumerator] allObjects] mutableCopy];
[self shuffleSequenceSelectedLoop];
return;
}
if (A == B) {
if (B != C) {
[sequenceSelected exchangeObjectAtIndex:i withObjectAtIndex:count-1];
} else {
// reshuffle
sequenceSelected = [[[sequenceSelected reverseObjectEnumerator] allObjects] mutableCopy];
[self shuffleSequenceSelectedLoop];
return;
}
}
}
}
}
。
克里斯托弗·约翰逊的回答很好,但并不是完全随机的。
给定一个由2个元素组成的数组,此函数总是返回逆数组,因为生成的是剩余索引的随机范围。更精确的
- (void)shuffle
{
NSUInteger count = [self count];
for (NSUInteger i = 0; i < count; ++i) {
NSInteger exchangeIndex = arc4random_uniform(count);
if (i != exchangeIndex) {
[self exchangeObjectAtIndex:i withObjectAtIndex:exchangeIndex];
}
}
}
NSUInteger randomIndex = arc4random() % [theArray count];
。
编辑:这不正确。出于参考目的,我没有删除这篇文章。请参阅有关此方法不正确的原因的注释。
此处为简单代码:
- (NSArray *)shuffledArray:(NSArray *)array
{
return [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
if (arc4random() % 2) {
return NSOrderedAscending;
} else {
return NSOrderedDescending;
}
}];
}
。
以上就是短码网小编为大家整理的《C# 什么是洗牌NSMutableArray的最佳方式?》相关内容,希望大家喜欢。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将联系本站反馈,一经查实,立即处理!
《C# 什么是洗牌NSMutableArray的最佳方式?》文档下载仅供参考学习,下载后请在24小时内删除。
转载注明出处:https://www.duanma.net/article/d384daa7377.html