সুইফটে সূচক এবং উপাদান সহ একটি লুপটি কীভাবে পুনরায় করা যায়


784

আমি কি অ্যারের উপরে পুনরাবৃত্তি করতে এবং পাইথনের গণনার মতো সূচক এবং উপাদান উভয়ই রাখতে পারি এমন কোনও ফাংশন আছে?

for index, element in enumerate(list):
    ...

উত্তর:


1659

হ্যাঁ. সুইফট 3.0.০ হিসাবে, যদি প্রতিটি উপাদানের মান সহ আপনার সূচকের প্রয়োজন হয় তবে আপনি অ্যারেতে পুনরাবৃত্তি করতে enumerated()পদ্ধতিটি ব্যবহার করতে পারেন । এটি সূচকের সমন্বয়ে যুক্ত জোড়গুলির ক্রম এবং অ্যারের প্রতিটি আইটেমের জন্য মান প্রদান করে। উদাহরণ স্বরূপ:

for (index, element) in list.enumerated() {
  print("Item \(index): \(element)")
}

সুইফট ৩.০ এর আগে এবং সুইফট ২.০ এর পরে, ফাংশনটি ডাকা হয়েছিল enumerate():

for (index, element) in list.enumerate() {
    print("Item \(index): \(element)")
}

সুইফট ২.০ এর আগে, enumerateএকটি বিশ্বব্যাপী ফাংশন ছিল।

for (index, element) in enumerate(list) {
    println("Item \(index): \(element)")
}

3
যদিও এটি টিউলের মতো মনে হচ্ছে, সুইফট ১.২ - ২.০ সম্পর্কে নিশ্চিত নয় - গণনাটি একটি এনিউমেটর সিক্যুয়েন্স <বেস: সিকোয়েন্সটাইপ> স্ট্রাক্ট দেয়।
এনস্টেইন

2
@ লিভিয়াথলন লক্ষণীয় বা পরিমাপযোগ্য পারফরম্যান্সের ওভারহেড যে বিষয়টি বিবেচনা করবে? নং
ড্যান রোজনস্টার্ক

সূচক অ্যাক্সেস পেয়ে কি একমাত্র সুবিধা enumerate?
মধু

28
সম্ভবত এগুলি পরিবর্তন হিসাবে পরিবর্তন করতে হবে, enumeratingসুইফট 4 এর জন্য! উত্তেজনাপূর্ণ!
ড্যান রোজনস্টার্ক

3
@ মধু for (index, element) inব্যবহারের সময় enumeratedবিভ্রান্তিমূলক। হওয়া উচিতfor (offset, element) in
লিও ডাবাস

115

সুইফট 5 একটি পদ্ধতির enumerated()জন্য ডাকে যা সরবরাহ করে Arrayenumerated()নিম্নলিখিত ঘোষণা আছে:

func enumerated() -> EnumeratedSequence<Array<Element>>

জোড়া (n, x) এর অনুক্রমটি প্রদান করে, যেখানে n একটি ক্রমাগত পূর্ণসংখ্যার শূন্য থেকে শুরু করে এবং x ক্রমের একটি উপাদানকে উপস্থাপন করে।


সাধারণ ক্ষেত্রে, আপনি enumerated()লুপের জন্য ব্যবহার করতে পারেন । উদাহরণ স্বরূপ:

let list = ["Car", "Bike", "Plane", "Boat"]
for (index, element) in list.enumerated() {
    print(index, ":", element)
}

/*
prints:
0 : Car
1 : Bike
2 : Plane
3 : Boat
*/

তবে লক্ষ করুন যে আপনি enumerated()লুপের জন্য ব্যবহারের মধ্যে সীমাবদ্ধ নন । প্রকৃতপক্ষে, আপনি যদি enumerated()নীচের কোডের অনুরূপ কোনও কিছুর জন্য লুপের সাথে ব্যবহার করার পরিকল্পনা করেন তবে আপনি এটি ভুল করছেন:

let list = [Int](1...5)
var arrayOfTuples = [(Int, Int)]()

for (index, element) in list.enumerated() {
    arrayOfTuples += [(index, element)]
}

print(arrayOfTuples) // prints [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]

এটি করার একটি দ্রুত উপায় হ'ল:

let list = [Int](1...5)
let arrayOfTuples = Array(list.enumerated())
print(arrayOfTuples) // prints [(offset: 0, element: 1), (offset: 1, element: 2), (offset: 2, element: 3), (offset: 3, element: 4), (offset: 4, element: 5)]

একটি বিকল্প হিসাবে, আপনি ব্যবহার করতে পারেন enumerated()সঙ্গে map:

let list = [Int](1...5)
let arrayOfDictionaries = list.enumerated().map { (a, b) in return [a : b] }
print(arrayOfDictionaries) // prints [[0: 1], [1: 2], [2: 3], [3: 4], [4: 5]]

তাছাড়া, যদিও এটি কিছু আছে সীমাবদ্ধতা , forEachলুপ জন্য একটি একটি ভাল প্রতিস্থাপন হতে পারে:

let list = [Int](1...5)
list.reversed().enumerated().forEach { print($0, ":", $1) }

/*
prints:
0 : 5
1 : 4
2 : 3
3 : 2
4 : 1
*/

enumerated()এবং ব্যবহার করে makeIterator()আপনি এমনকি নিজেরটিতে ম্যানুয়ালি পুনরাবৃত্তি করতে পারেন Array। উদাহরণ স্বরূপ:

import UIKit
import PlaygroundSupport

class ViewController: UIViewController {

    var generator = ["Car", "Bike", "Plane", "Boat"].enumerated().makeIterator()

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(type: .system)
        button.setTitle("Tap", for: .normal)
        button.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
        button.addTarget(self, action: #selector(iterate(_:)), for: .touchUpInside)
        view.addSubview(button)
    }

    @objc func iterate(_ sender: UIButton) {
        let tuple = generator.next()
        print(String(describing: tuple))
    }

}

PlaygroundPage.current.liveView = ViewController()

/*
 Optional((offset: 0, element: "Car"))
 Optional((offset: 1, element: "Bike"))
 Optional((offset: 2, element: "Plane"))
 Optional((offset: 3, element: "Boat"))
 nil
 nil
 nil
 */

1
সূচীতে অ্যাক্সেস পাওয়া কি একমাত্র সুবিধা enumerate?
মধু 1

52

সুইফট 2 দিয়ে শুরু করে, গণনার ফাংশনটি সংগ্রহের জন্য অনুরোধ করা দরকার:

for (index, element) in list.enumerate() {
    print("Item \(index): \(element)")
}

47

অভিধানের সাহায্যে এটি করার একটি উপায় সন্ধান করার সময় আমি এই উত্তরটি পেয়েছি এবং এটি সুনির্দিষ্টভাবে সহজেই খাপ খাইয়ে নেওয়া সহজ, কেবলমাত্র উপাদানটির জন্য একটি টুপল পাস করুন।

// Swift 2

var list = ["a": 1, "b": 2]

for (index, (letter, value)) in list.enumerate() {
    print("Item \(index): \(letter) \(value)")
}

18

আপনার পছন্দসই ফলাফল পেতে আপনি সহজেই গণনার লুপ ব্যবহার করতে পারেন:

সুইফট 2:

for (index, element) in elements.enumerate() {
    print("\(index): \(element)")
}

সুইফট 3 এবং 4:

for (index, element) in elements.enumerated() {
    print("\(index): \(element)")
}

অথবা একই ফলাফল পেতে আপনি কেবল লুপের মধ্য দিয়ে যেতে পারেন:

for index in 0..<elements.count {
    let element = elements[index]
    print("\(index): \(element)")
}

আশা করি এটা সাহায্য করবে.


14

বেসিক গণনা

for (index, element) in arrayOfValues.enumerate() {
// do something useful
}

বা সুইফট 3 সহ ...

for (index, element) in arrayOfValues.enumerated() {
// do something useful
}

অঙ্ক করা, ফিল্টার এবং মানচিত্র

তবে, আমি প্রায়শই মানচিত্র বা ফিল্টারটির সাথে মিশ্রণে গণনা ব্যবহার করি। উদাহরণস্বরূপ কয়েক অ্যারে অপারেটিং সহ।

এই অ্যারেটিতে আমি বিজোড় বা এমনকি সূচিকৃত উপাদানগুলি ফিল্টার করতে এবং ইনস থেকে ডাবলগুলিতে রূপান্তর করতে চেয়েছিলাম। সুতরাং enumerate()আপনাকে সূচক এবং উপাদানটি পেয়েছে, তারপরে ফিল্টারটি সূচীটি পরীক্ষা করে এবং শেষ পর্যন্ত ফলস্বরূপ দ্বিগুণ থেকে মুক্তি পেতে আমি এটিকে কেবলমাত্র উপাদানটিতে মানচিত্র করি।

let evens = arrayOfValues.enumerate().filter({
                            (index: Int, element: Int) -> Bool in
                            return index % 2 == 0
                        }).map({ (_: Int, element: Int) -> Double in
                            return Double(element)
                        })
let odds = arrayOfValues.enumerate().filter({
                            (index: Int, element: Int) -> Bool in
                            return index % 2 != 0
                        }).map({ (_: Int, element: Int) -> Double in
                            return Double(element)
                        })

9

.enumerate()কাজগুলি ব্যবহার করে, তবে এটি উপাদানটির সত্যিকারের সূচক সরবরাহ করে না; এটি কেবল 0 টি দিয়ে শুরু করে এবং প্রতিটি ক্রমিক উপাদানগুলির জন্য 1 দ্বারা বাড়িয়ে দেয় Int এটি সাধারণত অপ্রাসঙ্গিক, তবে ArraySliceটাইপটি ব্যবহার করার সময় অপ্রত্যাশিত আচরণের সম্ভাবনা রয়েছে । নিম্নলিখিত কোড নিন:

let a = ["a", "b", "c", "d", "e"]
a.indices //=> 0..<5

let aSlice = a[1..<4] //=> ArraySlice with ["b", "c", "d"]
aSlice.indices //=> 1..<4

var test = [Int: String]()
for (index, element) in aSlice.enumerate() {
    test[index] = element
}
test //=> [0: "b", 1: "c", 2: "d"] // indices presented as 0..<3, but they are actually 1..<4
test[0] == aSlice[0] // ERROR: out of bounds

এটি কিছুটা সংশ্লেষিত উদাহরণ এবং বাস্তবে এটি কোনও সাধারণ সমস্যা নয় তবে এখনও আমি মনে করি এটি ঘটতে পারে তা জেনে রাখা উচিত worth


2
it does not actually provide the true index of the element; it only provides an Int beginning with 0 and incrementing by 1 for each successive elementহ্যাঁ, এ কারণেই এটিকে গণনা বলা হয় । এছাড়াও, স্লাইস অ্যারে নয়, তাই আশ্চর্যরূপে এটি অন্যরকম আচরণ করে। এখানে কোনও ত্রুটি নেই - সবকিছু ডিজাইনের মাধ্যমে। :)
এরিক আয়া

5
সত্য, তবে আমি এটিকে কখনও বাগ বলিনি। এটি কেবল সম্ভাব্য অপ্রত্যাশিত আচরণ যা আমি ভেবেছিলাম তাদের জন্য এটি উল্লেখযোগ্য হবে যাঁরা জানেন না যে এটি অ্যারেস্লাইস ধরণের সাথে কীভাবে নেতিবাচক যোগাযোগ করতে পারে।
কোল ক্যাম্পবেল

আপনি প্রকৃত উপাদানটির সূচক পেতে কোনও উপায় সম্পর্কে অবগত আছেন - উদাহরণস্বরূপ যদি filterপ্রথমটি ব্যবহার করে থাকেন ?
আলেকজান্দ্রে ক্যাসাগন


9

সম্পূর্ণতার জন্য আপনি কেবল আপনার অ্যারে সূচকগুলি দিয়ে পুনরাবৃত্তি করতে পারেন এবং সংশ্লিষ্ট সূচীতে উপাদানটি অ্যাক্সেস করতে সাবস্ক্রিপ্ট ব্যবহার করতে পারেন:

let list = [100,200,300,400,500]
for index in list.indices {
    print("Element at:", index, " Value:", list[index])
}

ForEach ব্যবহার করে

list.indices.forEach {
    print("Element at:", $0, " Value:", list[$0])
}

সংগ্রহ enumerated()পদ্ধতি ব্যবহার করে । নোট করুন যে এটি offsetএবং এর সাথে টিপলগুলির একটি সংগ্রহ ফেরৎ দেয় element:

for item in list.enumerated() {
    print("Element at:", item.offset, " Value:", item.element)
}

প্রতিটি জন্য ব্যবহার:

list.enumerated().forEach {
    print("Element at:", $0.offset, " Value:", $0.element)
}

যারা মুদ্রণ করবে

উপাদানটিতে: 0 মান: 100

উপাদানটিতে: 1 মান: 200

উপাদানটিতে: 2 মান: 300 300

উপাদানটিতে: 3 মান: 400

উপাদানটিতে: 4 মান: 500

আপনার যদি অ্যারে সূচক (অফসেট নয়) এবং এর উপাদানগুলির প্রয়োজন হয় তবে আপনি সংগ্রহগুলি প্রসারিত করতে পারেন এবং সূচিযুক্ত উপাদানগুলি পেতে আপনার নিজস্ব পদ্ধতি তৈরি করতে পারেন:

extension Collection {
    func indexedElements(body: ((index: Index, element: Element)) throws -> Void) rethrows {
        var index = startIndex
        for element in self {
            try body((index,element))
            formIndex(after: &index)
        }
    }
}

অ্যালেক্সের পরামর্শ অনুসারে আর একটি সম্ভাব্য বাস্তবায়ন হ'ল সংগ্রহের সূচকগুলি এর উপাদানগুলির সাথে জিপ করা:

extension Collection {
    func indexedElements(body: ((index: Index, element: Element)) throws -> Void) rethrows {
        for element in zip(indices, self) { try body(element) }
    }
}

পরীক্ষামূলক:

let list =  ["100","200","300","400","500"]
list.dropFirst(2).indexedElements {
    print("Index:", $0.index, "Element:", $0.element)
}

এটি পি [rint হবে

সূচক: 2 উপাদান: 300

সূচক: 3 উপাদান: 400

সূচক: 4 উপাদান: 500


বিটিডাব্লু আপনি এর enumeratedIndicesসাথে লুপিং প্রয়োগ করে বাস্তবায়ন করতে পারেনzip(self.indices, self)
আলেকজান্ডার -

@ আলেকজান্ডার-রিইনস্টেটমোনিকা for element in zip(indices, self) { try body(element) }। বিটিডব্লিউ আমি যে নামকরণটি বেছে নিয়েছি তা পছন্দ করি না, indexedElementsএটি কী করে তার আরও ভাল বর্ণনা করতে পারে
লিও ডাবাস

ওও আমি মনে করি এটি আরও ভাল নাম। হ্যাঁ, একটি forলুপ কাজ করে তবে এটিওzip(self.indices, self) .forEach(body)
আলেকজান্ডার - মনিকা পুনরায়

@ আলেকজান্ডার-রেইনস্টেটমোনিকা forEachপর্দার পিছনে লুপের জন্য একটি কাজ করে। আমি এটিকে সাধারণ সরল github.com/apple/swift/blob/master/stdlib/public/core/… রাখতে পছন্দ করি @inlinable public func forEach( _ body: (Element) throws -> Void ) rethrows { for element in self { try body(element) } } }
লিও ডাবাস

7

এটি গণনার লুপের সূত্র:

for (index, value) in shoppingList.enumerate() {
print("Item \(index + 1): \(value)")
}

আরও বিশদ জন্য আপনি এখানে চেক করতে পারেন ।


5

আমি ব্যক্তিগতভাবে ব্যবহার পছন্দ forEach পদ্ধতিটি :

list.enumerated().forEach { (index, element) in
    ...
}

আপনি সংক্ষিপ্ত সংস্করণটিও ব্যবহার করতে পারেন:

list.enumerated().forEach { print("index: \($0.0), value: \($0.1)") }

4

এক্সকোড 8 এবং সুইফট 3: অ্যারে ব্যবহার করে অঙ্ক করা যেতে পারে tempArray.enumerated()

উদাহরণ:

var someStrs = [String]()

someStrs.append("Apple")  
someStrs.append("Amazon")  
someStrs += ["Google"]    


for (index, item) in someStrs.enumerated()  
{  
        print("Value at index = \(index) is \(item)").  
}

কনসোল:

Value at index = 0 is Apple
Value at index = 1 is Amazon
Value at index = 2 is Google

3

যারা ব্যবহার করতে চান তাদের জন্য forEach

সুইফট 4

extension Array {
  func forEachWithIndex(_ body: (Int, Element) throws -> Void) rethrows {
    try zip((startIndex ..< endIndex), self).forEach(body)
  }
}

অথবা

array.enumerated().forEach { ... }

2

আপনি যা করতে চাইছেন তার জন্য enumerated()আপনার অ্যারেতে পদ্ধতিটি ব্যবহার করা উচিত :

for (index, element) in list.enumerated() {
    print("\(index) - \(element)")
}

-1

আমরা এটি প্রয়োগের জন্য গণনা ফাংশন বলেছি। মত

অ্যারে.মেন্যারেটে (সূচক, উপাদান) জন্য)

// সূচক অ্যারের সূচক হয়

// এলিমেন্ট অ্যারের উপাদান

}

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