स्विफ्ट 3 में सरणी से ऑब्जेक्ट निकाल रहा है


92

अपने आवेदन में मैंने सेल में एक ऑब्जेक्ट जोड़ा जब सेल का चयन करें और अचयनित करें और सेल का चयन करते समय ऑब्जेक्ट को हटा दें। मैंने उस कोड का उपयोग किया लेकिन मुझे त्रुटि दें।

extension Array {
    func indexOfObject(object : AnyObject) -> NSInteger {
        return (self as NSArray).indexOfObject(object)
    }

    mutating func removeObject(object : AnyObject) {
        for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object) {
            self.removeAtIndex(index)
        }
    }
}

class MyViewController: UITableViewController {
    var arrContacts: [Any] = []
    var contacts: [Any] = []

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        arrContacts.removeObject(contacts[indexPath.row])
    }
}

यह मुझे इस तरह 2 त्रुटि देता है:

C-style for statement has been removed in Swift 3
Value of type '[Any]' has no member 'removeObject'

आप Set<Contact>एक ऐरे के बजाय एक का उपयोग कर सकते हैं । क्या आप अपनी संपर्क वस्तु के बारे में अधिक जानकारी प्रदान कर सकते हैं? यदि आपने इसे स्वयं बनाया है, तो आपको इसे एक सेट में रखने के लिए इसकी आवश्यकता होगी Hashableऔर Equatableइसे एक सेट में रखने के लिए
Paulw11

जवाबों:


164

स्विफ्ट बराबर करने NSMutableArrayकी removeObjectहै:

var array = ["alpha", "beta", "gamma"]

if let index = array.firstIndex(of: "beta") {
    array.remove(at: index)
}

यदि ऑब्जेक्ट अद्वितीय हैं । कास्ट करने NSArrayऔर इस्तेमाल करने की कोई आवश्यकता नहीं हैindexOfObject:

एपीआई index(of:भी काम करता है लेकिन यह एक अनावश्यक अंतर्निहित पुल का कारण बनता है NSArray

यदि एक ही वस्तु के कई उपयोग होते हैं filter। हालांकि डेटा स्रोत सरणियों जैसे मामलों में जहां एक सूचकांक किसी विशेष वस्तु firstIndex(ofसे जुड़ा होता है, बेहतर होता है क्योंकि यह उससे अधिक तेज होता है filter

अपडेट करें:

स्विफ्ट में 4.2+ आप एक या एक से अधिक घटनाओं को हटा सकते हैं betaसाथ removeAll(where:):

array.removeAll{$0 == "beta"}

33
यह सबसे अच्छा जवाब है, लेकिन इसे दूर करना बेवकूफी से परे है (वस्तु: "बीटा")।
जीपले

5
मुझे लगता .index(of: है कि संग्रह उपलब्ध Equatableप्रकारों के अनुसार ही उपलब्ध है ।
एडम वेट

@AdamWaite हाँ, लेकिन यह फाउंडेशन के प्रकारों पर भी लागू होता है।
14

यह सही नहीं है, अगर आपके पास एक से अधिक "बीटा" हैं तो क्या होगा? यह केवल तभी काम करता है जब सरणी में एक से अधिक घटनाएँ न हों। सही उत्तर एक फिल्टर का उपयोग कर रहा है या थोड़ी देर में इस जवाब को चला रहा है,while let index = array.index(of: "beta") { array.remove(at: index) }
जुनाज़ला

@juancazalla आप सही हैं, लेकिन यदि सरणी में एक से अधिक घटनाएँ हो सकती हैं तो filterसमाधान का उपयोग करें । लेकिन अगर वस्तुओं का हमेशा अनूठा उपयोग होता है, index(ofक्योंकि यह बहुत अधिक filter
परफ़ॉर्मेंट

71
var a = ["one", "two", "three", "four", "five"]

// Remove/filter item with value 'three'
a = a.filter { $0 != "three" }

7
यह सही स्विफ्ट समाधान है, जो भाषा द्वारा प्रस्तुत वाक्यविन्यास उपहारों का उपयोग करता है।
माइकल

1
यदि वस्तु एक वस्तु है तो क्या होगा?
टॉमस्वर

@TomSawyer किसी ऑब्जेक्ट को फ़िल्टर करने के लिए, $ 0 का उपयोग करें! ==
माइक टैवर्न

25

स्विफ्ट 3 के लिए, आप इंडेक्स का उपयोग कर सकते हैं (जहां :) और एक क्लोजर शामिल करें जो किसी भी वस्तु की तुलना एरे ($ 0) में करता है जो आप देख रहे हैं।

var array = ["alpha", "beta", "gamma"]
if let index = array.index(where: {$0 == "beta"}) {
  array.remove(at: index)
}

अगर मैं कई वस्तुओं को हटाना चाहता हूं तो क्या यह काम करेगा? जैसे (जहाँ: {$ 0 == "बीटा" || $ 0 == "गामा"})
इरशाद मोहम्मद

16

इस प्रकार का विस्तार करने के लिए एक और अच्छा और उपयोगी उपाय है:

extension Array where Element: Equatable {

    @discardableResult mutating func remove(object: Element) -> Bool {
        if let index = index(of: object) {
            self.remove(at: index)
            return true
        }
        return false
    }

    @discardableResult mutating func remove(where predicate: (Array.Iterator.Element) -> Bool) -> Bool {
        if let index = self.index(where: { (element) -> Bool in
            return predicate(element)
        }) {
            self.remove(at: index)
            return true
        }
        return false
    }

}

इस प्रकार, यदि आपके पास कस्टम ऑब्जेक्ट्स के साथ आपका सरणी है:

let obj1 = MyObject(id: 1)
let obj2 = MyObject(id: 2)
var array: [MyObject] = [obj1, obj2]

array.remove(where: { (obj) -> Bool in
    return obj.id == 1
})
// OR
array.remove(object: obj2) 

1
यह केवल तभी काम करता है जब सरणी में एक से अधिक घटनाएं न हों। सही उत्तर फ़िल्टर का उपयोग कर रहा है या थोड़ी देर में इस उत्तर को चला रहा है। इस एक्सटेंशन के उपयोगकर्ता के रूप में, मुझे उम्मीद है कि यह सभी घटनाओं को दूर करेगा और केवल एक ही नहीं
जुनाज़ुल्ला

यह अच्छा है, लेकिन यह होना चाहिए remove(element: Element)क्योंकि ऐरे में आप इंट, डबल जैसे प्रकार भी स्टोर कर सकते हैं - वे ऑब्जेक्ट नहीं हैं।
राडेक विलकैक

8

में स्विफ्ट 5 , इस का प्रयोग करें Extension:

extension Array where Element: Equatable{
    mutating func remove (element: Element) {
        if let i = self.firstIndex(of: element) {
            self.remove(at: i)
        }
    }
}

उदाहरण:

var array = ["alpha", "beta", "gamma"]
array.remove(element: "beta")

में स्विफ्ट 3 , इस का प्रयोग करें Extension:

extension Array where Element: Equatable{
    mutating func remove (element: Element) {
        if let i = self.index(of: element) {
            self.remove(at: i)
        }
    }
}

उदाहरण:

var array = ["alpha", "beta", "gamma"]
array.remove(element: "beta")

6
  1. for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object) सी-स्टाइल में लूप के लिए है और हटा दिया गया है

  2. अपने कोड को कुछ इस तरह बदलें कि यदि वह लूप हो जाए तो सभी समान ऑब्जेक्ट को हटा दें:

    let indexes = arrContacts.enumerated().filter { $0.element == contacts[indexPath.row] }.map{ $0.offset }
    for index in indexes.reversed() {
       arrContacts.remove(at: index)
    }
    

enumerated -> फ़िल्टर -> मानचित्र और निकालें (पर) स्मार्ट समाधान है। यह सलाह देते हैं
रयान एक्स

4

स्विफ्ट 4

var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]

if let index = students.firstIndex(where: { $0.hasPrefix("A") }) {
   students.remove(at: index)
}

3

स्विफ्ट 3 में इन ऑब्जेक्ट्स (नाम "सरणी") की एक सरणी से एक अनोखी वस्तु (जिसका नाम "objectToRemove") हटाने के लिए सही और काम कर रहे एक लाइन है:

if let index = array.enumerated().filter( { $0.element === objectToRemove }).map({ $0.offset }).first {
   array.remove(at: index)
}

1

स्विफ्ट 3 में यह प्रयास करें

array.remove(at: Index)

के बजाय

array.removeAtIndex(index)

अपडेट करें

"Declaration is only valid at file scope".

सुनिश्चित करें कि वस्तु दायरे में है। आप गुंजाइश "आंतरिक" दे सकते हैं, जो डिफ़ॉल्ट है।

index(of:<Object>) काम करने के लिए, कक्षा के अनुरूप होना चाहिए Equatable


1

में स्विफ्ट 3 और 4

var array = ["a", "b", "c", "d", "e", "f"]

for (index, element) in array.enumerated().reversed() {
    array.remove(at: index)
}

से स्विफ्ट 4.2 आप और अधिक उन्नत दृष्टिकोण (तेजी से और स्मृति कुशल) का उपयोग कर सकते

array.removeAll(where: { $0 == "c" })

के बजाय

array = array.filter { !$0.hasPrefix("c") }

यहाँ और पढ़ें


1

सरणी के लिए एक्सटेंशन इसे आसानी से करने के लिए और स्विफ्ट 4.2 और ऊपर के लिए जंजीर की अनुमति दें:

public extension Array where Element: Equatable {
    @discardableResult
    public mutating func remove(_ item: Element) -> Array {
        if let index = firstIndex(where: { item == $0 }) {
            remove(at: index)
        }
        return self
    }

    @discardableResult
    public mutating func removeAll(_ item: Element) -> Array {
        removeAll(where: { item == $0 })
        return self
    }
}

तर्क लेबल '(जहाँ :)' किसी भी उपलब्ध अधिभार से मेल नहीं खाता
jeet.chanchawat

1
@ jeet.chanchawat अच्छी तरह से शायद अलग स्विफ्ट संस्करण तो ... ओह यह सवाल 3 के लिए था? वैसे मुझे लगता है कि मेरे पास लेखन के समय ४.२ था, लेकिन अब याद नहीं है, बाद में इसकी जांच करेंगे, यह निश्चित रूप से मेरे लिए काम करता है
रेनिटिक

0

विशिष्ट वस्तु के सूचकांक को खोजने के लिए यह आधिकारिक उत्तर है, फिर आप उस सूचकांक का उपयोग करके किसी भी वस्तु को आसानी से निकाल सकते हैं:

var students = ["Ben", "Ivy", "Jordell", "Maxime"]
if let i = students.firstIndex(of: "Maxime") {
     // students[i] = "Max"
     students.remove(at: i)
}
print(students)
// Prints ["Ben", "Ivy", "Jordell"]

यहाँ लिंक है: https://developer.apple.com/documentation/swift/array/2994720-firstindex


0

यही मैंने प्रयोग किया है (स्विफ्ट 5) ...

    extension Array where Element:Equatable
    {
        @discardableResult
        mutating func removeFirst(_ item:Any ) -> Any? {
            for index in 0..<self.count {
                if(item as? Element == self[index]) {
                    return self.remove(at: index)
                }
            }
            return nil
        }
        @discardableResult
        mutating func removeLast(_ item:Any ) -> Any? {
            var index = self.count-1
            while index >= 0 {
                if(item as? Element == self[index]) {
                    return self.remove(at: index)
                }
                index -= 1
            }
            return nil
        }
    }

    var arrContacts:[String] = ["A","B","D","C","B","D"]
    var contacts: [Any] = ["B","D"]
    print(arrContacts)
    var index = 1
    arrContacts.removeFirst(contacts[index])
    print(arrContacts)
    index = 0
    arrContacts.removeLast(contacts[index])
    print(arrContacts)

परिणाम:

   ["A", "B", "D", "C", "B", "D"]
   ["A", "B", "C", "B", "D"]
   ["A", "B", "C", "D"]

महत्वपूर्ण: वह सरणी जिससे आप आइटम निकालते हैं, उसमें समतुल्य तत्व (जैसे ऑब्जेक्ट, स्ट्रिंग्स, संख्या, आदि) होने चाहिए

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.