0

I am trying to sort an array mapped with other three arrays. My main array is string+number i e ["Day 1","Day 2","Day 3"...] Other three array are also array of string.

Right now i am using following code.

var mainDayArray = ["Day 1","Day 2","Day 3","Day 4","Day 5","Day 6","Day 7","Day 8","Day 9","Day 10","Day 11","Day 12","Day 13"]
var timeArray = ["06:09 PM", "06:09 PM", "06:08 PM", "06:08 PM", "06:08 PM", "06:07 PM", "06:07 PM", "06:07 PM", "06:07 PM", "06:06 PM", "06:06 PM", "06:06 PM", "06:06 PM"]
var dateArray = ["Oct 1", "Oct 2", "Oct 3", "Oct 4", "Oct 5", "Oct 7", "Oct 4", "Oct 5", "Oct 9", "Nov 2", "Nov 3", "Nov 4", "Nov 01"]
var studentNameArray =["as","ab","vf","sd","fd","gr","ht","jh","kl","mn","sf","ts","at"]

let offsets = mainDayArray.enumerated().sorted { $0.element > $1.element }.map { $0.offset }

let sortedCompletedDayArray = offsets.map { mainDayArray[$0] }
let sortedCompletedDateArray = offsets.map { dateArray[$0] }
let sortedCompletedTimeArray = offsets.map { timeArray[$0] }
let sortedCompletedStudentNamesArray = offsets.map { studentNameArray[$0] }

But I am getting wrong data here. The output I am getting is below:

mainDayArray = ["Day 9","Day 8","Day 7","Day 6","Day 5","Day 4","Day 3","Day 2","Day 13","Day 12","Day 11","Day 1"]
12
  • 3
    Work with a custom struct instead of having the values in different arrays Commented Nov 1, 2023 at 6:37
  • Hi HangerRash this does not answer my question. This only works for two arrays but i have 4 arrays. And i am getting "No exact matches in call to subscript " issue when using this Commented Nov 1, 2023 at 6:38
  • @Abhishekkumar I would see JoakimDanielson's comment - it seems very weird to be working with four arrays which an "index dependent" Commented Nov 1, 2023 at 6:41
  • Hi Joakim actually it is already coded like this. Commented Nov 1, 2023 at 6:43
  • @Abhishekkumar Also, based on the linked example by HangerRash, I got your code to (I assume) to work (or at least sortedCompletedDayArray is in the correct order) Commented Nov 1, 2023 at 6:44

2 Answers 2

0

Your day array already looks sorted but just in case it's possible that your day array can be unsorted here is my solution:

var mainDayArray = ["Day 1","Day 2","Day 3","Day 4","Day 5","Day 6","Day 7","Day 8","Day 9","Day 10","Day 11","Day 12","Day 13"]

var timeArray = ["06:09 PM", "06:09 PM", "06:08 PM", "06:08 PM", "06:08 PM", "06:07 PM", "06:07 PM", "06:07 PM", "06:07 PM", "06:06 PM", "06:06 PM", "06:06 PM", "06:06 PM"]

var dateArray = ["Oct 1", "Oct 2", "Oct 3", "Oct 4", "Oct 5", "Oct 7", "Oct 4", "Oct 5", "Oct 9", "Nov 2", "Nov 3", "Nov 4", "Nov 01"]

var studentNameArray = ["as","ab","vf","sd","fd","gr","ht","jh","kl","mn","sf","ts","at"]


let offsets = mainDayArray.map(parseNumber).enumerated().sorted { $0.element < $1.element }.map(\.offset)

let sortedCompletedDayArray = offsets.map { mainDayArray[$0] }
let sortedCompletedDateArray = offsets.map { dateArray[$0] }
let sortedCompletedTimeArray = offsets.map { timeArray[$0] }
let sortedCompletedStudentNamesArray = offsets.map { studentNameArray[$0] }

/// Parses the day number from an array element stored in the `mainDayArray`.
/// - Parameter element: An element from the `mainDayArray`.
/// - Returns: The day number.
func parseNumber(from element: String) -> Int {
    Int(element.split(separator: " ").last!)!
}

However, this code assumed your mainDayArray will always be in the form of <string> + " " + <number>. If you take a look at the parseNumber(from:) function it splits the elements from the point it detects a space, ie., " ", and then from all the split values it assumes the last one will be the number of the day. Then, it simply casts that into an integer.

From there it's pretty straightforward. It sorts those using $0.element < $1.element and mainDayArray will be sorted.

Warning: This will cause a crash if your mainDayArray isn't in the proper format. Feel free to edit the parseNumber(from:) method as you see fit. This was just a quick implementation I did. The goal of that method is to simply take an element from the mainDayArray and retrieve the day number from it. So as long as that is achieved by the function this code will work.

Sign up to request clarification or add additional context in comments.

Comments

0

If I understand correctly, you want to sort all arrays based on the mainDate's order after sorting it (descending) by its values.

I suggest to first build a struct and encapsulate all data together like:

struct Student {
    let mainDate: String
    let time: String
    let date: String
    let name: String
}

let students = (0..<mainDayArray.count).map {
    Student(
        mainDate: mainDayArray[$0],
        time: timeArray[$0],
        date: dateArray[$0],
        name: studentNameArray[$0]
    )
}

Then you can sort by any property you want in the order you want like:

✅ Answer to your specific question about sorting number strings is here

let sortedStudents = students.sorted(using: KeyPathComparator(\.mainDate, comparator: .localizedStandard, order: .reverse))

Here I've sorted students based on their mainDate in the order of numbers. Note that passing localizedStandard will cause the Day 9 to be ordered after the Day 10 as expected.

Then if you actually need separated arrays, you can extract them from this source extremely simple like:

let sortedCompletedTimeArray = sortedStudents.map(\.time)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.