0

I am trying to filter a multi-dimensional array. Below is my swiftUI view.

import SwiftUI

struct Person {
    let name: String
    let job: String
    let age: Int
    let rating: Rating
    enum Rating: String {
        case Poor, Ok, Good, Excellent
    }
}


extension Person: CustomStringConvertible {
    var description: String {
        "Name: \(name), Job: \(job), Age: \(age), Rating: \(rating)"
    }
}

struct view: View {
    
    let name = "Paul"
    var array2d: [[String]].map(Person.init)
    let person = array2d.first(where: {$0.name == name})
    
    var body: some View {
        
        ZStack{
        Color.white
            Text("\(self.person)")
            
        }
            
        
    }
    
}

array2d is passed from the ViewController to the swiftUI view and it looks like this:

var array2d = [[Paul, CEO, 30, Good], [John, Manager, 45, Ok], [Scott, Assistant, 22, Poor], [Robert, CEO, 67, Excellent], [Paul, CEO, 56, Poor], [John, Manager, 23, Good]]

I am getting several errors with the the above code:

on var array2d: [[String]].map(Person.init) the errors:

Consecutive declarations on a line must be separated by ';'
Expected declaration

and on let person = array2d.first(where: {$0.name == name})

Cannot use instance member 'array2d' within property initializer; property initializers run before 'self' is available

Cannot use instance member 'name' within property initializer; property initializers run before 'self' is available

Value of type '[String]' has no member 'name'

6
  • 4
    I'd recommend to have a struct instead of an array to represent a person. Like struct Person { let name: String; let role: StringOrEnum, let age: Int, let someEnum: SomeEnumWithGoodOkExcellentEtc}. And you want to filter or find the first(where:). Imagine we have 2 "Paul"s: let paul = array2d.first(where: { $0.first == person } or let filtered = array2d.filter{ $0.first == person }? Commented Sep 25, 2020 at 16:23
  • @Jdv It is Swift naming convention to name all your classes, structures, enumerations and protocols starting with an Uppercase letter. struct AView: View {. For your cases, methods and variables they should start with a lowercase letter. case poor = "Poor", ok = "Ok", good = "Good", excellent = "Excellent" Commented Sep 25, 2020 at 21:27
  • Not related to your question but I think you should first try to learn the basics of the language (Swift) and UIKit framework. SwiftUI is too complex for beginners. Commented Sep 25, 2020 at 21:33
  • Is your data coming from a simple text file? Have you considered using a JSON String? Commented Sep 25, 2020 at 21:37
  • Appreciate your feedback on the previous comment @LeoDabus . My dafa is coming from a text file. Commented Sep 25, 2020 at 22:38

1 Answer 1

1

A direct answer to your question you can get the first array where the first element is equal to person:

let person = "Paul"
let array2d = [["Paul", "CEO", "30", "Good"], ["John", "Manager", "45", "Ok"], ["Scott", "Assistant", "22", "Poor"], ["Robert", "CEO", "67", "Excellent"], ["Paul", "CEO", "56", "Poor"], ["John", "Manager", "23", "Good"]]
if let array = array2d.first(where: {$0.first == person}) {
    print(array)  // ["Paul", "CEO", "30", "Good"]
}

But what you really should do is to struct your data and search your array by its name property:

struct Person {
    let name: String
    let job: String
    let age: Int
    let rating: Rating
    enum Rating: String {
        case poor, regular, good, excellent
    }
}

extension Person: CustomStringConvertible {
    var description: String {
        "Name: \(name), Job: \(job), Age: \(age), Rating: \(rating)"
    }
}

let name = "Paul"
let people = [("Paul", "CEO", 30, .good), ("John", "Manager", 45, .regular), ("Scott", "Assistant", 22, .poor), ("Robert", "CEO", 67, .excellent), ("Paul", "CEO", 56, .poor), ("John", "Manager", 23, .good)].map(Person.init)
if let person = people.first(where: {$0.name == name}) {
    print(person)  // "Name: Paul, Job: CEO, Age: 30, Rating: good\n"
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. That works in the dummy example I used, however I can't get it to work in the real swiftUI view I am using. I edited my question to show the swiftUI view I am working with. One thing I noticed is that the property people you created separates each array with (), in my case they are separated by [].
It is just a way I used to create an array of Person. It wasn’t my intention to shout how to parse your data
I understand. I edited my question to show how I tried to implement your solution and the errors I am getting. I am pretty new to swift and likely missing something obvious here. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.