दिलचस्प पोस्ट
लिनक्स पर अजगर के दो संस्करण कैसे 2.7 डिफ़ॉल्ट बनाने के लिए jQuery के स्वत: पूर्ण और एएसपी.नेट इनपुट () त्रुटि – NameError: नाम '…' परिभाषित नहीं है क्या एक ओरेकल एसक्यूएल क्वेरी है जो एक पंक्ति में कई पंक्तियाँ एकत्र करती है? अजगर नेस्टेड फ़ंक्शन बंद क्यों नहीं किए गए हैं? चर के साथ ब्रेस विस्तार? एकाधिक चेकबॉक्स से $ _POST प्राप्त करें jquery रोक बच्चे ट्रिगर माता पिता घटना स्विफ्ट में AVPlayerViewController (AVKit) के साथ वीडियो कैसे खेलें dyld: पुस्तकालय लोड नहीं किया गया: @ rpath / libswiftCore.dylib जावा में सूची के लिए मानचित्र को कैसे रूपांतरित करना है? MySQL त्रुटि 1025 (HY000) क्या है: './foo' के नाम पर त्रुटि (त्रुटि: 150) मतलब है? एंड्रॉइड: AsyncTask बनाम सेवा आर डेटाफ्रेम में शून्य के साथ मैं एनए वैल्यू कैसे बदल सकता हूं? <! – > काम नहीं कर रहा है

NSMutableArray को घुमाए जाने का सबसे अच्छा तरीका क्या है?

यदि आपके पास NSMutableArray , तो आप तत्वों को बेतरतीब ढंग से कैसे फेरते हैं?

(मेरे पास इस के लिए अपना जवाब है, जो नीचे पोस्ट किया गया है, लेकिन मैं कोको के लिए नया हूँ और मुझे पता है कि कोई बेहतर तरीका है, तो मुझे दिलचस्पी है।)


अद्यतन: आईओएस 10+ और मैकोज 10.12+ के रूप में @ मुकेश ने नोट किया है, एक -[NSMutableArray shuffledArray] एनएसएमयूटीएबलएआरआरएएएफआरएएफआरएआर -[NSMutableArray shuffledArray] विधि जो फेरबदल करने के लिए इस्तेमाल की जा सकती है विवरण के लिए https://developer.apple.com/documentation/foundation/nsarray/1640855-shuffledarray?language=objc देखें। (लेकिन ध्यान दें कि यह एक नई सरणी बनाता है, बजाय तत्वों को फेरबदल करने के बजाय।)

वेब के समाधान से एकत्रित समाधान "NSMutableArray को घुमाए जाने का सबसे अच्छा तरीका क्या है?"

आपको स्वैपऑब्जेक्ट आटइंडेक्स विधि की आवश्यकता नहीं है एक्सचेंज ऑब्जेक्टअट इंडेक्स: साथऑब्जेक्टआटइंडएक्स: पहले से मौजूद है।

मैंने इसे NSMutableArray के लिए एक श्रेणी जोड़कर हल किया।

संपादित करें: लादेन द्वारा जवाब देने के लिए अनावश्यक विधि को हटाया गया धन्यवाद।

संपादित करें: परिवर्तित (arc4random() % nElements) से arc4random_uniform(nElements) धन्यवाद ग्रेगरी Goltsov द्वारा जवाब और miho और blahdiblah द्वारा टिप्पणी

संपादित करें: लूप सुधार, रॉन द्वारा टिप्पणी करने के लिए धन्यवाद

संपादित करें: जोड़ा गया चेक कि सरणी खाली नहीं है, धन्यवाद महेश अग्रवाल द्वारा टिप्पणी के लिए

 // 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 

चूंकि मैं अभी तक टिप्पणी नहीं कर सकता, इसलिए मैंने सोचा कि मैं एक पूर्ण प्रतिक्रिया में योगदान देता हूं। मैंने क्रिस्टोफर जॉनसन को कई तरीकों से अपने प्रोजेक्ट के लिए कार्यान्वित किया (वास्तव में इसे यथासंभव संक्षिप्त बनाने की कोशिश), उनमें से एक 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 

यह 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

आईओएस 10 से आप नए shuffled एपीआई का उपयोग कर सकते हैं:

https://developer.apple.com/reference/foundation/nsarray/1640855-shuffled

 let shuffledArray = array.shuffled() 

शीर्ष उत्तर संपादित करने के बाद, मैंने थोड़ा सुधार और संक्षिप्त समाधान साझा करने के बारे में सोचा।

एल्गोरिथ्म एक समान है और साहित्य में " फिशर-येट्स फेरबदल " के रूप में वर्णित है

उद्देश्य सी में:

 @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 

स्विफ्ट 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)))) } } } 

स्विफ्ट 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]) } } } 

नोट: स्विफ्ट में एक और संक्षिप्त समाधान आईओएस 10 गेमप्लेकैट का उपयोग कर संभव है।

नोट: अस्थिर फेरबदल के लिए एक एल्गोरिथ्म (सभी पदों के साथ बदलना पड़ता है यदि गिनती> 1) भी उपलब्ध है

एक अच्छी लोकप्रिय लाइब्रेरी है, जिसकी इस विधि के रूप में इसका हिस्सा है, जिसे गीथहब में एसस्टुलकिट कहा जाता है । फ़ाइल NSMutableArray + SSToolkitAdditions.h में शफल विधि शामिल है। आप इसे भी उपयोग कर सकते हैं इस बीच, बहुत उपयोगी चीजें हैं।

इस पुस्तकालय का मुख्य पृष्ठ यहां है ।

यदि आप इसका उपयोग करते हैं, तो आपका कोड ऐसा होगा:

 #import <SSCategories.h> NSMutableArray *tableData = [NSMutableArray arrayWithArray:[temp shuffledArray]]; 

इस पुस्तकालय में एक पॉड भी है (देखें कोकाओप्स)

यदि तत्व दोहराता है

जैसे सरणी: एएएबीबी या बीबीएएए

केवल समाधान है: एबाएबाए

sequenceSelected चयनित है एक NSMutableArray जो वर्ग obj के तत्वों को संग्रहित करता है, जो कुछ अनुक्रम के संकेत हैं।

 - (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; } } } } } 

आईओएस 10 से, आप गेमप्लेट shuffled() एनएसएआरआरए shuffled() उपयोग कर सकते हैं। स्विफ्ट 3 में एरे के लिए यहां एक सहायक है:

 import GameplayKit extension Array { func shuffled() -> [Element] { return (self as NSArray).shuffled() as! [Element] } mutating func shuffle() { replaceSubrange(0..<count, with: shuffled()) } } 
 NSUInteger randomIndex = arc4random() % [theArray count]; 

क्रिस्टोफर जॉनसन का जवाब बहुत अच्छा है, लेकिन यह पूरी तरह यादृच्छिक नहीं है।

2 तत्वों की एक सरणी को देखते हुए, यह फ़ंक्शन हमेशा उलटा सरणी देता है, क्योंकि आप बाकी अनुक्रमितों पर आपके यादृच्छिक की श्रेणी का उत्पादन कर रहे हैं। एक और सटीक shuffle() फ़ंक्शन ऐसा होगा

 - (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]; } } } 

संपादित करें: यह सही नहीं है। संदर्भ उद्देश्यों के लिए, मैंने इस पोस्ट को नहीं हटाया। यह दृष्टिकोण सही नहीं है, इसलिए कारणों पर टिप्पणी देखें।

यहां सरल कोड:

 - (NSArray *)shuffledArray:(NSArray *)array { return [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { if (arc4random() % 2) { return NSOrderedAscending; } else { return NSOrderedDescending; } }]; }