0

jI have an array of objects with children objects.

I want to sort my array into an array of arrays based on the children objects

For instance: Array of

[employee, employee, employee, employee]

now what I want to do is sort this like this ->

[[employee.job.jobName = "baker",employee.job.jobName = "baker"],
[employee.job.jobName = "sweeper",employee.job.jobName = "sweeper"]]

The goal is to create a tableview where the section heading groups the employees where their job.jobName is the same. and the rows will be made up of those employees, their names etc. In order to do this, I need an array of unique job.jobNames for employees that make up the section count and then the array of employees within each section make up the row count.

I have tried using array.map and array.filter but I think I need a combination and I can't seem to work my head around this one. Any help would be greatly appreciated!

10
  • 1
    you can sort it using let sortedArray = yourArray.sort{$0.job < $1.job} or filter{$0.job == "baker"} Commented Jan 13, 2016 at 20:26
  • Thanks, I am able to sort it but I need to take employees with unique jobs, put those into arrays and put those arrays into an array. Would that accomplish this? Could I somehow use a nested sort? Commented Jan 13, 2016 at 20:31
  • 1
    edit your question with the employee class declaration and the expected results Commented Jan 13, 2016 at 20:32
  • The objects are rather large with many properties. I could do that but it might only take away from the main idea which is posted. An employee object with a job child object where I have an array of employee objects that need to be sorted into an array of arrays where the employees job.jobName s are all the same. I see I have left out that job is not a string. I'll add that. Commented Jan 13, 2016 at 20:36
  • Is the goal here to group these employee objects by their job? If so does the order of employees within each array or the order of those arrays of employees with the same job matter? Commented Jan 13, 2016 at 20:36

2 Answers 2

1

Here is my take on how I would split your employee array into an array of arrays.

// Just needed to make the example work
struct Job {
    var name: String
}

struct Employee {
    var job: Job
}
/////////////////////////////////////////

let employees = [Employee(job: Job(name: "baker")), Employee(job: Job(name: "sweeper")), Employee(job: Job(name: "baker")), Employee(job: Job(name: "sweeper"))]

var jobs = Set<String>()

employees.forEach { jobs.insert($0.job.name) }

let sortedJobs = jobs.sort()

var groupedEmployees = [[Employee]]()
for jobName in sortedJobs {
    groupedEmployees.append(employees.filter({ $0.job.name == jobName }))
}

print(groupedEmployees)

It produces the desired output of:

[[main.Employee(job: main.Job(name: "baker")), main.Employee(job: main.Job(name: "baker"))], [main.Employee(job: main.Job(name: "sweeper")), main.Employee(job: main.Job(name: "sweeper"))]]
Sign up to request clarification or add additional context in comments.

1 Comment

This is what I was initially looking to do. The other answer was also correct but this uses filter and sort to accomplish the task. Thanks Beardsley
0
import UIKit

/*Data Structure for Employee*/
class Employee:NSObject{
    /*Unemployed for default*/
    var job:String = "unemployed"

    init(job:String){
        self.job = job
    }

    override var description: String {
       return self.job
    }
}



/**Returns the array of arrays of enmployees sorted by jobs*/
func sortEmployees(employees:[Employee])->[[Employee]]
{
    //Sorting them by job
    let sorted = employees.sort({$0.job < $1.job})

    //Empty array of arrays
    var sortedEmployees = [[Employee]]()

    //job key
    var currentKey = ""
    for emp in sorted{
        let tempKey = emp.job
        //first element - edge case
        if sortedEmployees.count == 0
        {
            currentKey = tempKey
            sortedEmployees.append([emp])
        }
        else{
            if tempKey != currentKey{
                //create a new object
                sortedEmployees.append([emp])
                currentKey = tempKey
            }
            else{
                //get last array
                if let  lastArray = sortedEmployees.last{

                    var tempLast = lastArray
                    tempLast.append(emp)
                    sortedEmployees.removeLast()

                    sortedEmployees.append(tempLast)
                }
            }
        }
    }

    print(sortedEmployees)
    return sortedEmployees
}


/**Sample iVars*/
let emp1 = Employee(job: "baker")
let emp2 = Employee(job: "baker")
let emp3 = Employee(job: "sweeper")
let emp4 = Employee(job: "sweeper")


//Array with all of them
let array = [emp1, emp2, emp3, emp4]


let result = sortEmployees(array)
print(result)

3 Comments

That is what I was imagining. Great answer thanks. I wish there was an easier way with nesting filters or with map and maybe there is but this is great thanks!
There might be, but I am not aware of it. I refactored code into one easier to use method. Anytime.
@JanuszChudzynski why not simply override var description: String { return job } ?

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.