Sorting multiply nsmutablearrays

I have three nsmutablearrays and the are all connected.


In one I have a lot of dates.

In another I have a lot of text for each date.

And in the last one I have a lot of image paths for for each date.


Now I want to sort the one with date sp that when I put them info my UICollectionView the date are shown sorted.


How do I sorted my NSMUtableArray with dates and how do I sort the other NSMutableArrays so that the text and path still is in the same position as the date for them?


I hope someone can help me.


I'm using Swift 3.

Replies

I have three nsmutablearrays and the are all connected.

This approach is less than ideal. It would be better to put the data for each element into a struct and then store a (Swift) array of those structures. This change will solve your current problem and generally make things nicer.

If you can’t do that then the standard solution for this is to be a fourth array that contains a struct with two fields:

  • the sort key (the date in this case)

  • an index into the other arrays

You can then sort this array and follow the index to get to your real data.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

… is to be a fourth array …

… is to create a fourth array …

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks I'l try the fourth array

Can you point me in the right direction with struct and the fourth NSMutableArray?

Actually, I made this sound more complex than it really is. All you need to do is create an array of indexes into the arrays and sort those. For example:

let names    = ["Lancelot", "Robin", "Galahad", "Arthur"]
let questions = ["favourite colour", "capital of assyria", "favourite colour", "airspeed velocity of an unladen swallow"]
let answers  = ["blue", "I don't know that", "blue no yellow", "african or european?"]

let sortedIndices = names.indices.sorted(by: { (lhsIndex, rhsIndex) -> Bool in
    return names[lhsIndex] < names[rhsIndex]
})

for i in sortedIndices {
    print("--")
    print(names[i])
    print(questions[i])
    print(answers[i])
}

In this context,

names.indices
returns
0..<4
, that is, the indices of the array. I then sort those indices by looking at the name values. The end result is a set of indices that can be used to access any of the arrays.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for you reply.


I'm using NSMutableArrays and I get an error telling me that it does not know indices.


I tried your code and it was sorting but not the way I need it to do.


I have an array of dates: "16. aprill 2016", "15. aprill 2016", "17. aprill 2016"


And I have an arrays of text for each date: "bla. bla. 1", "bla. bla. 2", "bla. bla. 3"


And I have an array of image names: "image1", "image2", "image3"


Now I want to sort on the date so that the end result is like this:


"15. aprill 2016" - "bla. bla. 2" - "image2"

"16. aprill 2016" - "bla. bla. 1" - "image1"

"17. aprill 2016" - "bla. bla. 3" - "image3"


And when I try your code I don't get the same kind of result.

For a standard Swift array the

indices
property returns a list of indices for the array. For NSMutableArray the indices are always
0..<array.count
.

Honestly though, I think you’re way off in the weeds here. If I were in your shoes I’d use a single Swift array containing a struct rather than multiple NSMutableArray. This is going to result in nicer (and more Swift-ish) code.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I'm not that much into structs

Can you point me in the right direction?

I'm not that much into structs. Can you point me in the right direction?

Sure. To continue my previous example, here’s how I’d define a struct to hold all the info for a given knight.

struct Knight {
    var name: String
    var question: String
    var answer: String
}

Here’s how I’d set up an array of those:

let knights: [Knight] = [
    Knight(name: "Lancelot", question: "favourite colour",  answer: "blue"),
    Knight(name: "Robin",    question: "capital of assyria", answer: "I don't know that"),
    Knight(name: "Galahad",  question: "favourite colour",  answer: "blue no yellow"),
    Knight(name: "Arthur",  question: "airspeed velocity of an unladen swallow", answer: "african or european?")
]

and here’s how to get a sorted array from that:

let sortedKnights = knights.sorted(by: { (lhs, rhs) -> Bool in 
    return lhs.name < rhs.name 
})

If you’re starting off with multiple parallel arrays (for example, because that’s how the data is store in a file on disk), it’s relatively straightforward to build your array of structures from those arrays:

let names = ["Lancelot", "Robin", "Galahad", "Arthur"] 
let questions = ["favourite colour", "capital of assyria", "favourite colour", "airspeed velocity of an unladen swallow"] 
let answers = ["blue", "I don't know that", "blue no yellow", "african or european?"] 

let knights = (0..<names.count).map { index in
    return Knight(name: names[index], question: questions[index], answer: answers[index])
}

Structs are a critical part of any Swift app — for example, the bulk of the functionality in the Swift standard library is exposed via structs — so it’s really important that you get to know them. They are discussed in depth in The Swift Programming Language, and presumably all other tutorial introductions to Swift.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"