আমি কীভাবে সুইফটে একটি অ্যারে পরিবর্তন করব?


305

আমি কীভাবে এলোমেলো করে বা সুইফ্টের একটি অ্যারের মধ্যে উপাদানগুলি এলোমেলো করব? উদাহরণস্বরূপ, যদি আমার অ্যারেতে 52 টি প্লে কার্ড থাকে তবে আমি ডেকে সাফল্যের জন্য অ্যারেটি পরিবর্তন করতে চাই ।


2
এটি কোনও ভাষার সাথে নির্দিষ্ট নয়। কেবল কোনও বদলানো অ্যালগরিদম প্রয়োগ করুন ...
গ্যাব্রিয়েল পেট্রোনেলা

8
@ মিথরন্দির এটি সত্য নয়। রুবিতে একজন যেত array.shuffle। আপনার নিজের সংস্করণটি প্রয়োগ করার দরকার নেই। আমার ধারণা ওপিও তেমন কিছু খুঁজছিল।
লিনাস অলিয়েন্ডার

1
সতর্কতা অবলম্বন করুন, তবে কার্ডের ডেকে ডুবিয়ে রাখতে কেবল কোনও রদবদল অ্যালগরিদম ব্যবহার করবেন না।
njzk2

উত্তর:


626

এই উত্তরে কীভাবে দ্রুত এবং অভিন্ন অ্যালগরিদম (ফিশার-ইয়েটস) সুইফট ৪.২+ এ পরিবর্তন করা যায় এবং কীভাবে একই বৈশিষ্ট্যটি সুইফ্টের পূর্ববর্তী বিভিন্ন সংস্করণে যুক্ত করা যায় তা বিশদ করে। প্রতিটি সুইফ্ট সংস্করণটির নামকরণ এবং আচরণ সেই সংস্করণটির জন্য পরিবর্তিত এবং ননমুটটিং বাছাই করার পদ্ধতির সাথে মেলে।

সুইফট 4.2+ +

shuffleএবং shuffledস্থানীয় সুইফট 4.2 শুরু হয়। ব্যবহারের উদাহরণ:

let x = [1, 2, 3].shuffled()
// x == [2, 3, 1]

let fiveStrings = stride(from: 0, through: 100, by: 5).map(String.init).shuffled()
// fiveStrings == ["20", "45", "70", "30", ...]

var numbers = [1, 2, 3, 4]
numbers.shuffle()
// numbers == [3, 2, 1, 4]

সুইফট 4.0 এবং 4.1

এই এক্সটেনশানগুলি shuffle()কোনও পরিবর্তনযোগ্য সংগ্রহ (অ্যারে এবং অনিরাপদ মিউটেবল বাফারস) এবং shuffled()কোনও অনুক্রমের জন্য একটি পদ্ধতি যুক্ত করে:

extension MutableCollection {
    /// Shuffles the contents of this collection.
    mutating func shuffle() {
        let c = count
        guard c > 1 else { return }

        for (firstUnshuffled, unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
            // Change `Int` in the next line to `IndexDistance` in < Swift 4.1
            let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
            let i = index(firstUnshuffled, offsetBy: d)
            swapAt(firstUnshuffled, i)
        }
    }
}

extension Sequence {
    /// Returns an array with the contents of this sequence, shuffled.
    func shuffled() -> [Element] {
        var result = Array(self)
        result.shuffle()
        return result
    }
}

উপরের সুইফট ৪.২ উদাহরণগুলির মতো একই ব্যবহার।


সুইফট 3

এই এক্সটেনশনগুলি shuffle()কোনও পরিবর্তনযোগ্য সংগ্রহের shuffled()জন্য কোনও পদ্ধতি এবং যে কোনও অনুক্রমের জন্য একটি পদ্ধতি যুক্ত করে:

extension MutableCollection where Indices.Iterator.Element == Index {
    /// Shuffles the contents of this collection.
    mutating func shuffle() {
        let c = count
        guard c > 1 else { return }

        for (firstUnshuffled , unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
            // Change `Int` in the next line to `IndexDistance` in < Swift 3.2
            let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
            guard d != 0 else { continue }
            let i = index(firstUnshuffled, offsetBy: d)
            self.swapAt(firstUnshuffled, i)
        }
    }
}

extension Sequence {
    /// Returns an array with the contents of this sequence, shuffled.
    func shuffled() -> [Iterator.Element] {
        var result = Array(self)
        result.shuffle()
        return result
    }
}

উপরের সুইফট ৪.২ উদাহরণগুলির মতো একই ব্যবহার।


সুইফট 2

(অপ্রচলিত ভাষা: আপনি জুলাই 2018 থেকে আইটিউনস কানেক্টে প্রকাশের জন্য সুইফট 2.x ব্যবহার করতে পারবেন না)

extension MutableCollectionType where Index == Int {
    /// Shuffle the elements of `self` in-place.
    mutating func shuffleInPlace() {
        // empty and single-element collections don't shuffle
        if count < 2 { return }

        for i in startIndex ..< endIndex - 1 {
            let j = Int(arc4random_uniform(UInt32(count - i))) + i
            guard i != j else { continue }
            swap(&self[i], &self[j])
        }
    }
}

extension CollectionType {
    /// Return a copy of `self` with its elements shuffled.
    func shuffle() -> [Generator.Element] {
        var list = Array(self)
        list.shuffleInPlace()
        return list
    }
}

ব্যবহার:

[1, 2, 3].shuffle()
// [2, 3, 1]

let fiveStrings = 0.stride(through: 100, by: 5).map(String.init).shuffle()
// ["20", "45", "70", "30", ...]

var numbers = [1, 2, 3, 4]
numbers.shuffleInPlace()
// [3, 2, 1, 4]

সুইফট ১.২

(অপ্রচলিত ভাষা: আপনি জুলাই 2018 থেকে আইটিউনস কানেক্টে প্রকাশের জন্য সুইফট 1.x ব্যবহার করতে পারবেন না)

shuffle পরিবর্তিত অ্যারে পদ্ধতি হিসাবে

এই এক্সটেনশনটি আপনাকে Arrayস্থান পরিবর্তনযোগ্য দৃষ্টান্তটি বদল করতে দেবে :

extension Array {
    mutating func shuffle() {
        if count < 2 { return }
        for i in 0..<(count - 1) {
            let j = Int(arc4random_uniform(UInt32(count - i))) + i
            swap(&self[i], &self[j])
        }
    }
}
var numbers = [1, 2, 3, 4, 5, 6, 7, 8]
numbers.shuffle()                     // e.g., numbers == [6, 1, 8, 3, 2, 4, 7, 5]

shuffled একটি অ-পরিবর্তনকারী অ্যারে পদ্ধতি হিসাবে

এই এক্সটেনশানটি আপনাকে একটি Arrayউদাহরণের বদলানো কপিটি পুনরুদ্ধার করতে দেবে :

extension Array {
    func shuffled() -> [T] {
        if count < 2 { return self }
        var list = self
        for i in 0..<(list.count - 1) {
            let j = Int(arc4random_uniform(UInt32(list.count - i))) + i
            swap(&list[i], &list[j])
        }
        return list
    }
}
let numbers = [1, 2, 3, 4, 5, 6, 7, 8]
let mixedup = numbers.shuffled()     // e.g., mixedup == [6, 1, 8, 3, 2, 4, 7, 5]

1
আপনি যদি সুইফট ১.২ এ ফাংশন সংস্করণ চান তবে এটি আপডেট হওয়ার সাথে সাথে কিছুটা আপডেট হওয়া দরকার countElements, এবং এটি প্রতিস্থাপনের পরে countএখন T.Index.Distanceসীমাবদ্ধতা থাকা দরকার তাই এটি ফিরিয়ে দেয় C.Index.Distance == Int। এই সংস্করণটি কাজ করা উচিত: gist.github.com/airspeedswift/03d07a9dc86fabdc370f
এয়ারস্পীড বেগ

2
এগুলিই আসল আউটপুট — ফিশার-ইয়েটসের উত্সটির একটি নিরপেক্ষ র্যান্ডম অনুমান ফিরিয়ে দেওয়া উচিত, সুতরাং কোনও নির্দিষ্ট উপাদান স্থানান্তরিত হওয়ার কোনও প্রয়োজন নেই। সেখানে হয় একটি গ্যারান্টি কোনো উপাদান প্যাচসমূহ একবারের বেশি, কিন্তু কখনও কখনও "স্থানান্তর" একই সূচক হয়। সবচেয়ে সহজ [1, 2].shuffled()কেসটি [2, 1]কি প্রতিবার ফিরে আসবে ?
নাট কুক

1
আমি if count > 0"মারাত্মক ত্রুটি: আটকাতে" বিরতির জন্য বিন্যাস গঠন করতে পারি না: এটি কোনও "মারাত্মক ত্রুটি" রোধ করতে, পরিবর্তিত অ্যারে ফাংশনের শীর্ষে যুক্ত করেছিলাম যখন এটি খালি অ্যারে পাস করা হয়।
কার্ল স্মিথ

3
@ জান: হ্যাঁ, guard i != j else { continue }অদলবদলের আগে যুক্ত করুন। আমি একটি রাডার দায়ের করেছি, তবে নতুন আচরণটি ইচ্ছাকৃত।
নাট কুক

3
প্রকৃতপক্ষে shuffleInPlaceক্র্যাশ করতে পারে যদি সংগ্রহ সূচকগুলি শূন্য থেকে শুরু না হয়, উদাহরণস্বরূপ একটি অ্যারে টুকরো জন্য। for i in 0..<count - 1 হওয়া উচিত for i in startIndex ..< endIndex - 1(এবং তারপরে সুইফট 3 এ রূপান্তরটি প্রায় তুচ্ছ হয়ে ওঠে)।
মার্টিন আর

131

সম্পাদনা: অন্যান্য উত্তরে উল্লিখিত হিসাবে, সুইফট ৪.২ অবশেষে স্ট্যান্ডার্ড লাইব্রেরিতে এলোমেলো সংখ্যা জেনারেশন যুক্ত করে, অ্যারে শ্যাফলিংয়ের সাথে সম্পূর্ণ।

যাইহোক, GKRandom/ GKRandomDistributionGameplayKit মধ্যে স্যুট এখনও নতুন উপযোগী হতে পারে RandomNumberGeneratorপ্রোটোকল - আপনি GameplayKit RNGs এক্সটেনশন যোগ নতুন মান গ্রন্থাগার প্রোটোকল সাথে সামঞ্জস্য থেকে, আপনি সহজেই পেতে পারেন:

  • প্রেরণযোগ্য আরএনজিগুলি (যা পরীক্ষার প্রয়োজনে "র্যান্ডম" ক্রম পুনরুত্পাদন করতে পারে)
  • আরএনজি যারা গতির জন্য দৃust়তার ত্যাগ করে
  • অ-ইউনিফর্ম বিতরণ উত্পাদন করে এমন আরএনজিগুলি

... এবং এখনও সুইফটে দুর্দান্ত নতুন "নেটিভ" র্যান্ডম এপিআই ব্যবহার করুন।

এই উত্তরটির বাকি অংশগুলি এই জাতীয় আরএনজিগুলি এবং / অথবা পুরানো সুইফ্ট সংকলকগুলিতে তাদের ব্যবহার সম্পর্কিত।


এখানে ইতিমধ্যে কিছু ভাল উত্তর রয়েছে, পাশাপাশি সতর্কতা অবলম্বন না করাতে কেন নিজের শফল লিখতে ত্রুটি-ঝুঁকির কারণ হতে পারে তার কয়েকটি ভাল চিত্র রয়েছে।

আইওএস 9, ম্যাকোস 10.11, এবং টিভিএস 9 (বা তারপরে), আপনাকে নিজের লিখতে হবে না। আছে ফিশার-ইয়েটস একজন দক্ষ, সঠিক বাস্তবায়ন GameplayKit (যা, নাম সত্ত্বেও, শুধু গেম জন্য নয়) হবে।

আপনি যদি কেবল একটি অনন্য পরিবর্তন চান:

let shuffled = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: array)

আপনি যদি কোনও শ্যাফেল বা শ্যাফেলের সিরিজটির প্রতিলিপি তৈরি করতে সক্ষম হতে চান তবে একটি নির্দিষ্ট এলোমেলো উত্স চয়ন করুন এবং বীজ করুন; যেমন

let lcg = GKLinearCongruentialRandomSource(seed: mySeedValue)
let shuffled = lcg.arrayByShufflingObjects(in: array)

আইওএস 10 / ম্যাকোস 10.12 / টিভিএস 10 এ, এক্সটেনশনের মাধ্যমে সাফ করার জন্য একটি সুবিধামত বাক্য গঠন রয়েছে NSArray। অবশ্যই আপনি যখন একটি সুইফ্ট ব্যবহার করছেন তখন এটি কিছুটা জটিল Array((এবং এটি সুইফটে ফিরে আসার উপাদান উপাদান হারিয়ে ফেলে):

let shuffled1 = (array as NSArray).shuffled(using: random) // -> [Any]
let shuffled2 = (array as NSArray).shuffled() // use default random source

তবে এটির জন্য টাইপ-সংরক্ষণের সুইফট র‍্যাপার তৈরি করা বেশ সহজ:

extension Array {
    func shuffled(using source: GKRandomSource) -> [Element] {
        return (self as NSArray).shuffled(using: source) as! [Element]
    }
    func shuffled() -> [Element] {
        return (self as NSArray).shuffled() as! [Element]
    }
}
let shuffled3 = array.shuffled(using: random)
let shuffled4 = array.shuffled()

6
গেমপ্লেকিতে এমন কী কী অন্যান্য দরকারী ইউটিলিটিগুলি পাওয়া যেতে পারে তা আমাকে অবাক করে দেয় যা আমি কখনই অন্বেষণ করি নি!
রিচার্ড ভেনেবল

6
গ্রাফ অনুসন্ধান, ট্রি অনুসন্ধান, নিয়ম সিস্টেম ... প্রচুর পরিমাণে সামগ্রী যা গেম ডিজাইনে এবং অন্যথায় উভয় ক্ষেত্রে সহায়ক।
রিক্সার

5
সুইফ্ট 3 / আইওএস 10-এ, এটিকে পরিবর্তন করা হয়েছে:let shuffled = lcg.arrayByShufflingObjects(in: array)
ইভান পন

30

ইন সুইফট 2.0 , GameplayKit রেসকিউ আসতে পারে! ( iOS9 বা তার পরে সমর্থিত )

import GameplayKit

func shuffle() {
    array = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(array)
}

5
গেমপ্লেকিটটি কেবল বদলে যাওয়া অ্যারে পেতে আমদানি করা কোনও দুর্দান্ত ধারণা বলে মনে হয় না
লোপ

3
কেন? এটি সিস্টেমের অংশ, বাইনারি যুক্ত করে না।
আবাইজার্ন

3
আপনি সহজেই আমদানির সুযোগও করতে পারেনimport GameplayKit.GKRandomSource
জেআরজি-বিকাশকারী

26

এখানে সম্ভবত কিছুটা ছোট

sorted(a) {_, _ in arc4random() % 2 == 0}

1
@ মোবি sortফাংশনটির উপাদানগুলি অর্ডার করতে একটি বন্ধ হওয়া দরকার। এই সমাপ্তিতে দুটি প্যারামিটার লাগে (এলেম 1, এলেম 2) এবং প্রথম মানটি যদি দ্বিতীয় মানের আগে উপস্থিত হয় এবং অন্যথায় মিথ্যা হয় তবে সত্যটি অবশ্যই ফিরে আসতে হবে। এর পরিবর্তে যদি আমরা একটি এলোমেলো বুলেটিয়ানটি ফিরে পাই ... তবে আমরা কেবল পুরো জিনিসটি মিশ্রিত করি :)
জিন লে মাইগানান

2
এখানে কোনও গণিতবিদ নিশ্চিত বা অস্বীকার করার জন্য?
জিন লে মাইগানান

9
যেমন pjs অন্য খুব অনুরূপ উত্তরের প্রতিক্রিয়া হিসাবে উল্লেখ করেছে, এটি ফলাফলের অভিন্ন বিতরণ তৈরি করবে না । নাট কুকের উত্তরে প্রদর্শিত হিসাবে ফিশার-ইয়েটস সাফেল ব্যবহার করুন ।
রব

1
এটি একটি চতুর কৌশল, তবে এলোমেলো মানের গুণমানের দিক থেকে এটি অত্যন্ত খারাপ। একটির জন্য, এই arc4random_uniform()বন্ধটি ব্যবহার করা উচিত, কারণ এটি বর্তমানে মডুলোর পক্ষপাতের সাপেক্ষে। দ্বিতীয়ত, আউটপুটটি বাছাই করা অ্যালগরিদমের উপর খুব দৃ depends়ভাবে নির্ভর করে (যা উত্সের দিকে তাকানো ছাড়া আমাদের জানা নেই)।
আলেকজান্ডার - মনিকা

1
এই সহজ পদ্ধতির সাথে চালিয়ে যাওয়া, এটি বেশ সুন্দরভাবে কাজ করবে বলে মনে হচ্ছে: collection.sorted { _,_ in arc4random_uniform(1) == 0 }
617 এ 9:55

7

টেকিং Nate এর অ্যালগরিদম আমি এই সুইফট 2 এবং প্রোটোকল এক্সটেনশনগুলি সহ দেখাবে কিভাবে দেখতে চেয়েছিলেন।

এটিই আমি নিয়ে এসেছি।

extension MutableCollectionType where Self.Index == Int {
    mutating func shuffleInPlace() {
        let c = self.count
        for i in 0..<(c - 1) {
            let j = Int(arc4random_uniform(UInt32(c - i))) + i
            swap(&self[i], &self[j])
        }
    }
}

extension MutableCollectionType where Self.Index == Int {
    func shuffle() -> Self {
        var r = self
        let c = self.count
        for i in 0..<(c - 1) {
            let j = Int(arc4random_uniform(UInt32(c - i))) + i
            swap(&r[i], &r[j])
        }
        return r
    }
}

এখন, কোন MutableCollectionTypeপ্রদত্ত এই পদ্ধতি এটি ব্যবহার করে ব্যবহার করতে পারেন Intএকটি যেমনIndex


6

আমার ক্ষেত্রে, অ্যারেতে জিনিসগুলি অদলবদল করতে আমার কিছু সমস্যা হয়েছিল। তারপরে আমি আমার মাথাটি আঁচড়ে এলাম এবং চাকাটি পুনর্বহাল করতে গেলাম।

// swift 3.0 ready
extension Array {

    func shuffled() -> [Element] {
        var results = [Element]()
        var indexes = (0 ..< count).map { $0 }
        while indexes.count > 0 {
            let indexOfIndexes = Int(arc4random_uniform(UInt32(indexes.count)))
            let index = indexes[indexOfIndexes]
            results.append(self[index])
            indexes.remove(at: indexOfIndexes)
        }
        return results
    }

}

5

এটি সুইট 4 (এক্সকোড 9) এর জন্য ফিশার-ইয়েটস সাফল্যের জন্য নেটের প্রয়োগের একটি সংস্করণ ।

extension MutableCollection {
    /// Shuffle the elements of `self` in-place.
    mutating func shuffle() {
        for i in indices.dropLast() {
            let diff = distance(from: i, to: endIndex)
            let j = index(i, offsetBy: numericCast(arc4random_uniform(numericCast(diff))))
            swapAt(i, j)
        }
    }
}

extension Collection {
    /// Return a copy of `self` with its elements shuffled
    func shuffled() -> [Element] {
        var list = Array(self)
        list.shuffle()
        return list
    }
}

পরিবর্তনগুলি হ'ল:

  • সীমাবদ্ধতা Indices.Iterator.Element == Indexএখন Collectionপ্রোটোকলের অংশ , এবং আর এক্সটেনশনের উপর চাপানো হবে না।
  • এক্সচেঞ্জিং উপাদানগুলি swapAt()সংগ্রহকে কল করে অবশ্যই SE-0173 অ্যাডেরMutableCollection.swapAt(_:_:) তুলনা করুন
  • Elementজন্য একটি উপনাম Iterator.Element

3

এটি আমি ব্যবহার করি:

func newShuffledArray(array:NSArray) -> NSArray {
    var mutableArray = array.mutableCopy() as! NSMutableArray
    var count = mutableArray.count
    if count>1 {
        for var i=count-1;i>0;--i{
            mutableArray.exchangeObjectAtIndex(i, withObjectAtIndex: Int(arc4random_uniform(UInt32(i+1))))
        }
    }
    return mutableArray as NSArray
}

3

সুইফট 4 এলোমেলো লুপ জন্য একটি মধ্যে একটি অ্যারের উপাদান যেখানে আমি মিক্সিং অনুপাত

var cards = [Int]() //Some Array
let i = 4 // is the mixing ratio
func shuffleCards() {
    for _ in 0 ..< cards.count * i {
        let card = cards.remove(at: Int(arc4random_uniform(UInt32(cards.count))))
        cards.insert(card, at: Int(arc4random_uniform(UInt32(cards.count))))
    }
}

বা এক্সটেনশন সহ

func shuffleCards() {
    for _ in 0 ..< cards.count * i {
        let card = cards.remove(at: cards.count.arc4random)
        cards.insert(card, at: cards.count.arc4random)
    }
}
extension Int {
    var arc4random: Int {
        if self > 0 {
            print("Arc for random positiv self \(Int(arc4random_uniform(UInt32(self))))")
        return Int(arc4random_uniform(UInt32(self)))
        } else if self < 0 {
            print("Arc for random negotiv self \(-Int(arc4random_uniform(UInt32(abs(self)))))")
            return -Int(arc4random_uniform(UInt32(abs(self))))
        } else {
            print("Arc for random equal 0")
            return 0
        }
    }
}

2

নেট কুকের উত্তর অনুসরণ করে সুইফট 3 সমাধান: সূচক 0 দিয়ে শুরু হয় তবে কাজ করুন, নীচের মন্তব্য দেখুন)

extension Collection {
    /// Return a copy of `self` with its elements shuffled
    func shuffle() -> [Generator.Element] {
        var list = Array(self)
        list.shuffleInPlace()
        return list
    } }

extension MutableCollection where Index == Int {
    /// Shuffle the elements of `self` in-place.
    mutating func shuffleInPlace() {
        // empty and single-element collections don't shuffle
        if count < 2 { return }
        let countInt = count as! Int

    for i in 0..<countInt - 1 {
        let j = Int(arc4random_uniform(UInt32(countInt - i))) + i
            guard i != j else { continue }
            swap(&self[i], &self[j])
        }
    }
}

1
সংগ্রহ সূচকগুলি 0 থেকে শুরু না হলে এটি ক্র্যাশ হতে পারে, উদাহরণস্বরূপ অ্যারে স্লাইসের জন্য। var a = [1, 2, 3, 4, 5, 6][3..<6]; a.shuffleInPlace()কয়েকবার চালানোর চেষ্টা করুন । - সঠিক সমাধানের জন্য স্ট্যাকওভারফ্লো.com/ a/ 37843901/1187415 দেখুন ।
মার্টিন আর

2

এটি সরলতম উপায়ে এটি করা হয়। import Gamplaykitআপনার ভিসিতে এবং নীচের কোডটি ব্যবহার করুন। এক্সকোড 8-এ পরীক্ষিত।

 import GameplayKit

 let array: NSArray = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]

 override func viewDidLoad() {
    super.viewDidLoad()

    print(array.shuffled())  
}

আপনি যদি কোনও অ্যারে থেকে একটি বদল স্ট্রিং পেতে চান তবে নীচের কোডটি ব্যবহার করতে পারেন ..

func suffleString() {

    let ShuffleArray = array.shuffled()

    suffleString.text = ShuffleArray.first as? String

    print(suffleString.text!)

}

2

সুইফট 3 এর সাহায্যে, আপনি যদি কোনও অ্যারে স্থান পরিবর্তন করতে চান বা কোনও অ্যারে থেকে নতুন শিফলেড অ্যারে পেতে চান তবে আপনাকে সহায়তা AnyIteratorকরতে পারে। ধারণাটি হ'ল আপনার অ্যারে থেকে সূচকগুলির একটি অ্যারে তৈরি করা, সেই সূচকগুলিকে কোনও AnyIteratorউদাহরণ এবং swap(_:_:)ফাংশন দিয়ে বদলে দেওয়া এবং AnyIteratorঅ্যারের সম্পর্কিত উপাদানটির সাথে এই উদাহরণের প্রতিটি উপাদান ম্যাপ করা ।


নিম্নলিখিত খেলার মাঠের কোডটি এটি কীভাবে কাজ করে তা দেখায়:

import Darwin // required for arc4random_uniform

let array = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
var indexArray = Array(array.indices)
var index = indexArray.endIndex

let indexIterator: AnyIterator<Int> = AnyIterator {
    guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
        else { return nil }

    index = nextIndex
    let randomIndex = Int(arc4random_uniform(UInt32(index)))
    if randomIndex != index {
        swap(&indexArray[randomIndex], &indexArray[index])
    }

    return indexArray[index]
}

let newArray = indexIterator.map { array[$0] }
print(newArray) // may print: ["Jock", "Ellie", "Sue Ellen", "JR", "Pamela", "Bobby"]

আপনি অ্যারে থেকে নতুন শিফলেড অ্যারে পেতে পূর্ববর্তী কোডটি রিফ্যাক্টর করতে পারেন এবং shuffled()একটি Arrayএক্সটেনশনের অভ্যন্তরে একটি ফাংশন তৈরি করতে পারেন:

import Darwin // required for arc4random_uniform

extension Array {

    func shuffled() -> Array<Element> {
        var indexArray = Array<Int>(indices)        
        var index = indexArray.endIndex

        let indexIterator = AnyIterator<Int> {
            guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
                else { return nil }

            index = nextIndex                
            let randomIndex = Int(arc4random_uniform(UInt32(index)))
            if randomIndex != index {
                swap(&indexArray[randomIndex], &indexArray[index])
            }

            return indexArray[index]
        }

        return indexIterator.map { self[$0] }
    }

}

ব্যবহার:

let array = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
let newArray = array.shuffled()
print(newArray) // may print: ["Bobby", "Pamela", "Jock", "Ellie", "JR", "Sue Ellen"]
let emptyArray = [String]()
let newEmptyArray = emptyArray.shuffled()
print(newEmptyArray) // prints: []

পূর্ববর্তী কোডের বিকল্প হিসাবে, আপনি কোনও অ্যারের জায়গায় স্থান পরিবর্তন করতে shuffle()একটি Arrayএক্সটেনশনের অভ্যন্তরে একটি ফাংশন তৈরি করতে পারেন :

import Darwin // required for arc4random_uniform

extension Array {

    mutating func shuffle() {
        var indexArray = Array<Int>(indices)
        var index = indexArray.endIndex

        let indexIterator = AnyIterator<Int> {
            guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
                else { return nil }

            index = nextIndex                
            let randomIndex = Int(arc4random_uniform(UInt32(index)))
            if randomIndex != index {
                swap(&indexArray[randomIndex], &indexArray[index])
            }

            return indexArray[index]
        }

        self = indexIterator.map { self[$0] }
    }

}

ব্যবহার:

var mutatingArray = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
mutatingArray.shuffle()
print(mutatingArray) // may print ["Sue Ellen", "Pamela", "Jock", "Ellie", "Bobby", "JR"]

1

আপনি জেনেরিক swapফাংশনটি পাশাপাশি ব্যবহার করতে পারেন এবং উল্লিখিত ফিশার-ইয়েটস বাস্তবায়ন করতে পারেন :

for idx in 0..<arr.count {
  let rnd = Int(arc4random_uniform(UInt32(idx)))
  if rnd != idx {
    swap(&arr[idx], &arr[rnd])
  }
}

বা কম ভার্বোস:

for idx in 0..<steps.count {
  swap(&steps[idx], &steps[Int(arc4random_uniform(UInt32(idx)))])
}

2
এটি এখানে বর্ণিত একটি ত্রুটি দ্বারা খুব অল্প সময়েই ভয়াবহভাবে ক্ষতিগ্রস্থ হয় যার দ্বারা মানটি সর্বদা তার আসল অবস্থান থেকে অদলবদল হয়। এটি দিয়ে প্রতিকার করা হয় । এছাড়াও, অর্থবছরে, আপনি সাধারণত বারবার থেকে নেমে (অথবা থেকে আপনি পুনরুক্তি যদি করতে , আপনাকে স্বীকার করেছে উত্তর মধ্যে Nate শো মত সূচক বাছাই)। ফিশার-ইয়েটস আলোচনার আধুনিক অ্যালগরিদম বিভাগটি দেখুন । let rnd = Int(arc4random_uniform(UInt32(idx + 1)))arr.count - 110arr.count - 1
রব

1

কাজ !!। জীবগুলি স্থানান্তরিত করার জন্য অ্যারে to

extension Array
{
    /** Randomizes the order of an array's elements. */
    mutating func shuffle()
    {
        for _ in 0..<10
        {
            sort { (_,_) in arc4random() < arc4random() }
        }
    }
}

var organisms = [
    "ant",  "bacteria", "cougar",
    "dog",  "elephant", "firefly",
    "goat", "hedgehog", "iguana"]

print("Original: \(organisms)")

organisms.shuffle()

print("Shuffled: \(organisms)")


0

সুইফট 3.0.০ তে একটি বীজের সাথে কীভাবে একটি অ্যারে এলোমেলো করা যায়।

extension MutableCollection where Indices.Iterator.Element == Index {
    mutating func shuffle() {
        let c = count
        guard c > 1 else { return }


        for (firstUnshuffled , unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
            srand48(seedNumber)
            let number:Int = numericCast(unshuffledCount)
            let r = floor(drand48() * Double(number))

            let d: IndexDistance = numericCast(Int(r))
            guard d != 0 else { continue }
            let i = index(firstUnshuffled, offsetBy: d)
            swap(&self[firstUnshuffled], &self[i])
        }
    }
}


0

এটি আমি ব্যবহার করি:

import GameplayKit

extension Collection {
    func shuffled() -> [Iterator.Element] {
        let shuffledArray = (self as? NSArray)?.shuffled()
        let outputArray = shuffledArray as? [Iterator.Element]
        return outputArray ?? []
    }
    mutating func shuffle() {
        if let selfShuffled = self.shuffled() as? Self {
            self = selfShuffled
        }
    }
}

// Usage example:

var numbers = [1,2,3,4,5]
numbers.shuffle()

print(numbers) // output example: [2, 3, 5, 4, 1]

print([10, "hi", 9.0].shuffled()) // output example: [hi, 10, 9]

0

সাধারণ উদাহরণ:

extension Array {
    mutating func shuffled() {
        for _ in self {
            // generate random indexes that will be swapped
            var (a, b) = (Int(arc4random_uniform(UInt32(self.count - 1))), Int(arc4random_uniform(UInt32(self.count - 1))))
            if a == b { // if the same indexes are generated swap the first and last
                a = 0
                b = self.count - 1
            }
            swap(&self[a], &self[b])
        }
    }
}

var array = [1,2,3,4,5,6,7,8,9,10]
array.shuffled()
print(array) // [9, 8, 3, 5, 7, 6, 4, 2, 1, 10]

0

ওয়ার্কিং অ্যারে এক্সটেনশন (পরিবর্তন এবং অ-পরিবর্তনকারী)

সুইফট 4.1 / এক্সকোড 9

শীর্ষের উত্তরটিকে অবহেলা করা হয়েছে, তাই আমি সুইফট, সুইফট ৪.১ (এক্সকোড ৯) এর নতুন সংস্করণে একটি অ্যারে পরিবর্তন করতে আমার নিজের এক্সটেনশনটি তৈরি করার বিষয়টি নিজেই গ্রহণ করেছি:

extension Array {

// Non-mutating shuffle
    var shuffled : Array {
        let totalCount : Int = self.count
        var shuffledArray : Array = []
        var count : Int = totalCount
        var tempArray : Array = self
        for _ in 0..<totalCount {
            let randomIndex : Int = Int(arc4random_uniform(UInt32(count)))
            let randomElement : Element = tempArray.remove(at: randomIndex)
            shuffledArray.append(randomElement)
            count -= 1
        }
        return shuffledArray
    }

// Mutating shuffle
    mutating func shuffle() {
        let totalCount : Int = self.count
        var shuffledArray : Array = []
        var count : Int = totalCount
        var tempArray : Array = self
        for _ in 0..<totalCount {
            let randomIndex : Int = Int(arc4random_uniform(UInt32(count)))
            let randomElement : Element = tempArray.remove(at: randomIndex)
            shuffledArray.append(randomElement)
            count -= 1
        }
        self = shuffledArray
    }
}

নন-মিউটেশন শফলকে কল করুন [Array] -> [Array]:

let array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

print(array.shuffled)

arrayএলোমেলো ক্রমে এই মুদ্রণ ।


রূপান্তরকারী শাফলকে কল করুন [Array] = [Array]:

var array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

array.shuffle() 
// The array has now been mutated and contains all of its initial 
// values, but in a randomized shuffled order

print(array) 

এটি arrayএর বর্তমান ক্রমে মুদ্রণ করে যা ইতিমধ্যে এলোমেলোভাবে বদলে গেছে।


আশা করি এটি সবার জন্য কাজ করে, আপনার যদি কোনও প্রশ্ন, পরামর্শ বা মন্তব্য থাকে তবে নির্দ্বিধায় জিজ্ঞাসা করুন!


0

সুইফট 4-এ

func createShuffledSequenceOfNumbers(max:UInt)->[UInt] {

    var array:[UInt]! = []
    var myArray:[UInt]! = []
    for i in 1...max {
        myArray.append(i)
    }
    for i in 1...max {
        array.append(i)
    }
    var tempArray:[Int]! = []
    for index in 0...(myArray.count - 1) {

        var isNotFinded:Bool = true
        while(isNotFinded){

            let randomNumber = arc4random_uniform(UInt32(myArray.count))
            let randomIndex = Int(randomNumber)

            if(!tempArray.contains(randomIndex)){
                tempArray.append(randomIndex)

                array[randomIndex] = myArray[index]
                isNotFinded = false
            }
        }
    }

    return array
}

0

আপনি যদি লুপ ফাংশনের জন্য সাধারণ সুইফট ব্যবহার করতে চান তবে এটি ব্যবহার করুন ->

var arrayItems = ["A1", "B2", "C3", "D4", "E5", "F6", "G7", "H8", "X9", "Y10", "Z11"]
var shuffledArray = [String]()

for i in 0..<arrayItems.count
{
    let randomObject = Int(arc4random_uniform(UInt32(items.count)))

    shuffledArray.append(items[randomObject])

    items.remove(at: randomObject)
}

print(shuffledArray)

এক্সটেনশন -> ব্যবহার করে সুইফ্ট অ্যারে গ্রাস করুন

extension Array {
    // Order Randomize
    mutating func shuffle() {
        for _ in 0..<count {
            sort { (_,_) in arc4random() < arc4random() }
        }
    }
}

0

দ্রুত 4.2 হিসাবে দুটি কার্যকরী ফাংশন রয়েছে:

// shuffles the array in place
myArray.shuffle()

এবং

// generates a new array with shuffled elements of the old array
let newArray = myArray.shuffled()

-2

এখানে এমন কিছু কোড রয়েছে যা খেলার মাঠে চলে। আপনাকে আসল এক্সকোড প্রকল্পে ডারউইন আমদানি করতে হবে না।

import darwin

var a = [1,2,3,4,5,6,7]

func shuffle<ItemType>(item1: ItemType, item2: ItemType) -> Bool {
    return drand48() > 0.5
}

sort(a, shuffle)

println(a)

7
এটি ফলাফলগুলির একটি অ-ইউনিফর্ম বিতরণ দেয়। এটি ও (এন লগ এন) হবে, যেখানে কোনও ফিশার-ইয়েটস সাফল্য ও (এন) সময়ে অভিন্ন বিতরণ ফলাফল দেয়।
pjs

এছাড়াও drand48()একই ছদ্ম র্যান্ডম সংখ্যা সব দেয়, যদি না আপনি মতো একটি বীজ সেটsrand48(Int(arc4random()))
Kametrixom

-3

আমি যখন এক্সকোড সংস্করণটি 7.4 বিটাতে আপগ্রেড করব তখন এটি "অদলবদল (& স্ব [i], এবং স্ব [জে])" এ থামবে।
মারাত্মক ত্রুটি: নিজের সাথে কোনও অবস্থানের অদলবদল সমর্থনযোগ্য নয়

আমি কারণটি খুঁজে পেয়েছি যে আমি = জে (অদলবদলের কার্যটি বিস্ফোরিত হবে)

সুতরাং আমি নীচে হিসাবে একটি শর্ত যোগ করুন

if (i != j){
    swap(&list[i], &list[j])
}

YA! আমার জন্য ঠিক আছে.


এটি ক্রিসের উত্তরের মন্তব্য বলে মনে হচ্ছে , মূল প্রশ্নের উত্তর নয়।
মোগসদাদ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.