সুইফটে সূচী সহ মানচিত্র বা হ্রাস করুন


143

সুইফ ইন mapবা reduceসুইফটে অ্যারের সূচক পাওয়ার কোনও উপায় আছে কি ? আমি each_with_indexরুবির মতো কিছু খুঁজছি ।

func lunhCheck(number : String) -> Bool
{
    var odd = true;
    return reverse(number).map { String($0).toInt()! }.reduce(0) {
        odd = !odd
        return $0 + (odd ? ($1 == 9 ? 9 : ($1 * 2) % 9) : $1)
    }  % 10 == 0
}

lunhCheck("49927398716")
lunhCheck("49927398717")

আমি উপরেরodd পরিবর্তনশীল থেকে মুক্তি পেতে চাই ।

উত্তর:


314

আপনি enumerateএকটি ক্রম ( Array, Stringইত্যাদি) কে একটি পূর্ণসংখ্যার কাউন্টার এবং এবং উপাদানকে একত্রে জোড়া দিয়ে টিপলগুলির ক্রমতে রূপান্তর করতে ব্যবহার করতে পারেন । এটাই:

let numbers = [7, 8, 9, 10]
let indexAndNum: [String] = numbers.enumerate().map { (index, element) in
    return "\(index): \(element)"
}
print(indexAndNum)
// ["0: 7", "1: 8", "2: 9", "3: 10"]

enumerateসংজ্ঞা সংযোগ

দ্রষ্টব্য যে এটি সংগ্রহের সূচক পাওয়ার মতো নয় same enumerateআপনাকে একটি পূর্ণসংখ্যার কাউন্টার ফেরত দেয়। এটি অ্যারের সূচক হিসাবে একই, তবে স্ট্রিং বা অভিধানে খুব কার্যকর হবে না। প্রতিটি উপাদান সহ প্রকৃত সূচক পেতে, আপনি ব্যবহার করতে পারেন zip:

let actualIndexAndNum: [String] = zip(numbers.indices, numbers).map { "\($0): \($1)" }
print(actualIndexAndNum)
// ["0: 7", "1: 8", "2: 9", "3: 10"]

এর সাথে একটি অঙ্কিত ক্রম ব্যবহার reduceকরার সময়, আপনি ইতিমধ্যে পদ্ধতিতে স্বাক্ষরে জমে থাকা / বর্তমানের টিউপলটি যেহেতু সূচি এবং উপাদানটিকে একটি টুপলে আলাদা করতে পারবেন না। পরিবর্তে, আপনি ব্যবহার করতে হবে .0এবং .1আপনার দ্বিতীয় প্যারামিটার উপর reduceঅবসান:

let summedProducts = numbers.enumerate().reduce(0) { (accumulate, current) in
    return accumulate + current.0 * current.1
    //                          ^           ^
    //                        index      element
}
print(summedProducts)   // 56

উপরের দিকে সুইফট ৩.০

যেহেতু সুইফ্ট ৩.০ সিনট্যাক্সটি একেবারেই আলাদা।
এছাড়াও, আপনি অভিধানে অ্যারে মানচিত্রের জন্য সংক্ষিপ্ত বাক্য গঠন / ইনলাইন ব্যবহার করতে পারেন:

let numbers = [7, 8, 9, 10]
let array: [(Int, Int)] = numbers.enumerated().map { ($0, $1) }
//                                                     ^   ^
//                                                   index element

এটি উত্পাদন করে:

[(0, 7), (1, 8), (2, 9), (3, 10)]


5
সুইফ্ট ২.০ এ আপনাকে করতে হবে:numbers.enumerate().map { (index, element) in ...
রবার্ট

@ চর্লিমার্টিন: আপনি .reduceপরে enumerate()বা ব্যবহার করতে পারেন zip
নাট কুক

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

সুইফ্ট 5- enumerateএ এখন রয়েছেenumerated
লুস্টিগ

10

Swift 2.1আমি পরবর্তী ফাংশন লিখেছি জন্য :

extension Array {

 public func mapWithIndex<T> (f: (Int, Element) -> T) -> [T] {     
     return zip((self.startIndex ..< self.endIndex), self).map(f)
   }
 }

এবং তারপরে এটি ব্যবহার করুন:

    let numbers = [7, 8, 9, 10]
    let numbersWithIndex: [String] = numbers.mapWithIndex { (index, number) -> String in
        return "\(index): \(number)" 
    }
    print("Numbers: \(numbersWithIndex)")

8

সুইফট 3 এর সাথে, যখন আপনার কাছে এমন কোনও বস্তু রয়েছে যা Sequenceপ্রোটোকলের সাথে সামঞ্জস্য করে এবং আপনি এর প্রতিটি উপাদানকে এর সূচকের সাথে যুক্ত করতে চান, আপনি enumerated()পদ্ধতিটি ব্যবহার করতে পারেন ।

উদাহরণ স্বরূপ:

let array = [1, 18, 32, 7]
let enumerateSequence = array.enumerated() // type: EnumerateSequence<[Int]>
let newArray = Array(enumerateSequence)
print(newArray) // prints: [(0, 1), (1, 18), (2, 32), (3, 7)]
let reverseRandomAccessCollection = [1, 18, 32, 7].reversed()
let enumerateSequence = reverseRandomAccessCollection.enumerated() // type: EnumerateSequence<ReverseRandomAccessCollection<[Int]>>
let newArray = Array(enumerateSequence)
print(newArray) // prints: [(0, 7), (1, 32), (2, 18), (3, 1)]
let reverseCollection = "8763".characters.reversed()
let enumerateSequence = reverseCollection.enumerated() // type: EnumerateSequence<ReverseCollection<String.CharacterView>>
let newArray = enumerateSequence.map { ($0.0 + 1, String($0.1) + "A") }
print(newArray) // prints: [(1, "3A"), (2, "6A"), (3, "7A"), (4, "8A")]

অতএব, সহজতম ক্ষেত্রে আপনি এই জাতীয় খেলার মাঠে Luhn অ্যালগরিদম প্রয়োগ করতে পারেন:

let array = [8, 7, 6, 3]
let reversedArray = array.reversed()
let enumerateSequence = reversedArray.enumerated()

let luhnClosure = { (sum: Int, tuple: (index: Int, value: Int)) -> Int in
    let indexIsOdd = tuple.index % 2 == 1
    guard indexIsOdd else { return sum + tuple.value }
    let newValue = tuple.value == 9 ? 9 : tuple.value * 2 % 9
    return sum + newValue
}

let sum = enumerateSequence.reduce(0, luhnClosure)
let bool = sum % 10 == 0
print(bool) // prints: true

আপনি যদি একটি থেকে শুরু করেন তবে আপনি Stringএটি এর মতো প্রয়োগ করতে পারেন:

let characterView = "8763".characters
let mappedArray = characterView.flatMap { Int(String($0)) }
let reversedArray = mappedArray.reversed()
let enumerateSequence = reversedArray.enumerated()

let luhnClosure = { (sum: Int, tuple: (index: Int, value: Int)) -> Int in
    let indexIsOdd = tuple.index % 2 == 1
    guard indexIsOdd else { return sum + tuple.value }
    let newValue = tuple.value == 9 ? 9 : tuple.value * 2 % 9
    return sum + newValue
}

let sum = enumerateSequence.reduce(0, luhnClosure)
let bool = sum % 10 == 0
print(bool) // prints: true

আপনার যদি সেই ক্রিয়াকলাপগুলির পুনরাবৃত্তি প্রয়োজন হয় তবে আপনি নিজের কোডটিকে একটি এক্সটেনশনে রিফ্যাক্টর করতে পারেন:

extension String {

    func luhnCheck() -> Bool {
        let characterView = self.characters
        let mappedArray = characterView.flatMap { Int(String($0)) }
        let reversedArray = mappedArray.reversed()
        let enumerateSequence = reversedArray.enumerated()

        let luhnClosure = { (sum: Int, tuple: (index: Int, value: Int)) -> Int in
            let indexIsOdd = tuple.index % 2 == 1
            guard indexIsOdd else { return sum + tuple.value }
            let newValue = tuple.value == 9 ? 9 : tuple.value * 2 % 9
            return sum + newValue
        }

        let sum = enumerateSequence.reduce(0, luhnClosure)
        return sum % 10 == 0
    }

}

let string = "8763"
let luhnBool = string.luhnCheck()
print(luhnBool) // prints: true

বা, খুব সংক্ষিপ্তভাবে:

extension String {

    func luhnCheck() -> Bool {
        let sum = characters
            .flatMap { Int(String($0)) }
            .reversed()
            .enumerated()
            .reduce(0) {
                let indexIsOdd = $1.0 % 2 == 1
                guard indexIsOdd else { return $0 + $1.1 }
                return $0 + ($1.1 == 9 ? 9 : $1.1 * 2 % 9)
        }
        return sum % 10 == 0
    }

}

let string = "8763"
let luhnBool = string.luhnCheck()
print(luhnBool) // prints: true

2

নেট কুকের উদাহরণ ছাড়াও map, আপনি এই আচরণটিও প্রয়োগ করতে পারেন reduce

let numbers = [1,2,3,4,5]
let indexedNumbers = reduce(numbers, [:]) { (memo, enumerated) -> [Int: Int] in
    return memo[enumerated.index] = enumerated.element
}
// [0: 1, 1: 2, 2: 3, 3: 4, 4: 5]

নোট করুন যে EnumerateSequence বন্ধ হিসাবে পাস হিসাবে enumeratedএকটি নেস্টেড ফ্যাশন মধ্যে পচা যাবে না, এইভাবে টিপল এর সদস্যদের বন্ধের অভ্যন্তরে পচে যেতে হবে (অর্থাত্ enumerated.index)।


2

এটি নিক্ষেপ ও পুনরায় ব্যবহার করে সুইফট ২.১-এর জন্য একটি কার্যক্ষম কালেকশন টাইপ এক্সটেনশন:

extension CollectionType {

    func map<T>(@noescape transform: (Self.Index, Self.Generator.Element) throws -> T) rethrows -> [T] {
        return try zip((self.startIndex ..< self.endIndex), self).map(transform)
    }

}

আমি জানি এটি আপনি যা চেয়েছিলেন তা নয়, তবে আপনার সমস্যা সমাধান করে। আপনি কিছু না বাড়িয়ে এই সুইফট ২.০ লুহান পদ্ধতিটি ব্যবহার করতে পারেন:

func luhn(string: String) -> Bool {
    var sum = 0
    for (idx, value) in string.characters.reverse().map( { Int(String($0))! }).enumerate() {
        sum += ((idx % 2 == 1) ? (value == 9 ? 9 : (value * 2) % 9) : value)
    }
    return sum > 0 ? sum % 10 == 0 : false
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.