NSArray mit NSArray filtern

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • NSArray mit NSArray filtern

    Hallo zusammen,

    ich komme mal wieder so überhaupt nicht weiter und benötige mal wieder dringend eine zweite Meinung. Ich versuche mein GesamtArray gemäß den Werten aus dem FavoritenArray zu filtern (siehe ersten CodeTag).

    Quellcode

    1. var FavoritenArray:NSArray = ["1","3"]
    2. var GesamtArray:Array = [
    3. [
    4. "id": "1",
    5. "name" : "test name",
    6. "ort" : "test ort",
    7. "lat" : 45.123,
    8. "long" : 67.1234
    9. ],
    10. [
    11. "id": "2",
    12. "name" : "test name 2",
    13. "ort" : "test ort 2",
    14. "lat" : 45.123,
    15. "long" : 67.1234
    16. ]
    17. ]
    18. FavoritenArray
    19. GesamtArray
    20. let filter = GesamtArray.filter {FavoritenArray.contains($0["id"] as! String)}
    21. filter
    Alles anzeigen

    Dies funktioniert auch soweit. Wenn ich das GesamtArray jetzt allerdings als NSArray deklariere, funktioniert es nicht mehr.

    Quellcode

    1. //: Playground - noun: a place where people can play
    2. import UIKit
    3. var FavoritenArray:NSArray = ["1","3"]
    4. var GesamtArray:NSArray = [
    5. [
    6. "id": "1",
    7. "name" : "test name",
    8. "ort" : "test ort",
    9. "lat" : 45.123,
    10. "long" : 67.1234
    11. ],
    12. [
    13. "id": "2",
    14. "name" : "test name 2",
    15. "ort" : "test ort 2",
    16. "lat" : 45.123,
    17. "long" : 67.1234
    18. ]
    19. ]
    20. FavoritenArray
    21. GesamtArray
    22. let filter = GesamtArray.filter {FavoritenArray.contains($0["id"] as! String)}
    23. filter
    Alles anzeigen
    Wie muss ich es anstellen, dass ich das selbe Ergebnis erhalte?
  • Die Filterfunktion ist spezifisch Swift. Entweder Du verwendest eine entsprechende NSArray-Filtermethode aus Foundation oder Du castest an der Stelle zu einem Swift-Array: (GesamtArray as? Array)?.filter{ … }

    Die Frage ist eigentlich eher, warum willst Du unbedingt mit NSArray operieren?
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Vielen Dank für die schnelle Antwort.
    Ich habe einen DetailView mit einem Favoritenbutton. Wenn dieser gedrückt wird, wird die ID aus dem geladenen Dictionary in einem Array, ebenfalls in einer Plist gespeichert.
    Jetzt war ich der Meinung, dass ich die Gesamte Plist in einen TableView laden kann und die Gesamte Plist mit dem Array aus IDs zu filtern, um nur die Favoriten zu erhalten.

    Ich habe schon probiert das ganze anders zu lösen, dies war allerdings die erste Version die einigermaßen funktional erschien, bin aber natürlich für jeden Rat dankbar.
    Ich bin leider noch nicht so erfahren. Würdest du es anders lösen?




    Quellcode

    1. import UIKit
    2. class Favoriten: UITableViewController {
    3. //MARK: - Table View
    4. @IBOutlet var myTable: UITableView!
    5. //MARK: - Standard UserDefaults
    6. let defaults = UserDefaults.standard
    7. //MARK: - Plist Arrays
    8. var GesamtArray:NSArray!
    9. var FavoritenArray:NSArray!
    10. var plistPath:String!
    11. //MARK: - View Did Appear
    12. override func viewDidAppear(_ animated: Bool) {
    13. //MARK: Load Favorites Array
    14. let appDelegate = UIApplication.shared.delegate as! AppDelegate
    15. plistPath = appDelegate.plistPathInDocument
    16. // Extract the content of the file as NSData
    17. let data:Data = FileManager.default.contents(atPath: plistPath)!
    18. do{
    19. FavoritenArray = try PropertyListSerialization.propertyList(from: data, options: PropertyListSerialization.MutabilityOptions.mutableContainersAndLeaves, format: nil) as! NSMutableArray
    20. }catch{
    21. print("Error occured while reading from the plist file")
    22. }
    23. self.FavoritenFilter()
    24. }
    25. func FavoritenFilter() {
    26. let IstEinFavorit = (GesamtArray as Array).filter {FavoritenArray.contains($0["id"] as Any)}
    27. print(IstEinFavorit)
    28. }
    29. //MARK: - View Did Load
    30. override func viewDidLoad() {
    31. super.viewDidLoad()
    32. myTable.delegate = self
    33. myTable.dataSource = self
    34. //MARK: - load plist file
    35. if let path = Bundle.main.path(forResource: "Gesamt", ofType: "plist") {
    36. GesamtArray = NSArray(contentsOfFile: path) as! NSMutableArray!
    37. }
    38. }
    39. override func didReceiveMemoryWarning() {
    40. super.didReceiveMemoryWarning()
    41. // Dispose of any resources that can be recreated.
    42. }
    43. // MARK: - Table view data source
    44. override func numberOfSections(in tableView: UITableView) -> Int {
    45. // #warning Incomplete implementation, return the number of sections
    46. return 1
    47. }
    48. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    49. // #warning Incomplete implementation, return the number of rows
    50. return GesamtArray!.count
    51. }
    52. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    53. let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    54. let row = indexPath.row
    55. let Favorit:NSDictionary = GesamtArray.object(at: row) as! NSDictionary
    56. cell.textLabel?.text = Favorit.object(forKey: "titel") as! String?
    57. return cell
    58. }
    Alles anzeigen
  • Dein Ansatz lässt vermuten, dass Du sehr viel Erfahrung mit relationalen Datenbanksystemen hast.
    Das ist sehr schön und total wichtig, in diesem Fall jedoch eher hinderlich.

    Auch Swift hantiert intern mit Referenzen, zumindest wenn es NSArray und andere Foundation Objekte trifft.
    Bei Swift Arrays, Swift Dictionaries, Swift Strings etc.pp. ist es ein wenig anders, da diese Datentypen als Strukturen vorliegen und entsprechend nicht by-reference sondern by-value übergeben werden.

    Zurück zum Thema.
    Anstatt in Deinem Array die IDs irgendeiner Json/XML Representation zu speichern, auf die Du Dich dann in Deiner Favoritenansicht beziehst, kannst Du einfach die Json/XML Representation in einem Favoritenarray speichern.

    Ein TableView, dass diese Favoriten dann darstellen soll, kann einfach das Array als Datenquelle nehmen und darstellen.

    Der Speicherverbrauch ist dann ziemlich genau 1 Zeiger pro Representation und damit vermutlich sogar noch kleiner als mit einem String.
    Vom Rechenaufwand des Filterns ganz zu schweigen.

    Davon ab solltest Du wirklich überlegen, die Representation in ein eigenes Objekt zu überführen. ;)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Hallo Marco,

    vielen Dank für die Antwort.
    Sehr viel Erfahrung in relationalen Datenbanksystemen ist vielleicht etwas zu viel gesagt, jedoch weiß ich wie sie funktionieren.
    Ich habe das ganze jetzt wie von dir beschrieben umgesetzt und es funktioniert auch wirklich gut.

    Jetzt renne ich jedoch in das nächste Problem. Bis jetzt habe ich wie unten beschrieben im DetailView immer geprüft ob in dem Array, in dem ich bis jetzt die IDs gespeichert habe,
    die ID des DetailViews enthalten war und dementsprechend den Favoritenbutton auf isSelected oder ebene auch nicht gesetzt.
    Wie kann ich jetzt prüfen ob die ID in dem Array aus Dictionaries enthalten ist?

    Das ist jetzt wahrscheinlich eine doofe Frage, jedoch komme ich hier, wie man evtl. schon an den Versuchen sieht, überhaupt nicht weiter und wäre über einen Ansatz echt glücklich.

    Quellcode

    1. func CheckIfItsAFavorite() {
    2. let Key = FavoritenArray.mutableArrayValue(forKey: "id")
    3. if Key.contains(WaterfallDetail.IDText) {
    4. Favoriten.isSelected = true
    5. } else {
    6. Favoriten.isSelected = false
    7. }
    8. }
    Mit ein wenig try and error sowie ein bisschen Recherche hat sich auch das Problem gelöst. Danke nochmals für die Hilfe.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Capk ()