1

Is it possible to iterate through an NSDictionary in a specific order so I can save an index for an key-value pair in CoreData, based on the order that the data is originally typed? i.e in the code below Set 1 would have an index of 1, set 2 - 2 and set 3 - 3 rather than at random, as is normal NSDictionary behaviour? Thanks in advance if anyone can either give a solution, or tell me its not possible!

let string1 = "rain, wait, train".wordsInArray
let string2 = "oil, join, coin".wordsInArray
let string3 = "made, came, same".wordsInArray

let lists: [String: [String]] =
    ["Set 1: List 1": string1,
        "Set 1: List 2": string2,
        "Set 1: List 3": string3]

var index = 0

For list in lists {
 list.listIndex = index
 index = index + 1
 coreDataStack.saveMainContext() 
}

extension String {
    var wordsInArray:[String] {
        return componentsSeparatedByCharactersInSet(NSCharacterSet.punctuationCharacterSet()).joinWithSeparator("").componentsSeparatedByString(" ")
    }
richc
  • 1,648
  • 5
  • 20
  • 48
  • A dictionary is an unordered collection. There is no guarantee that things will stay in the same order and any index you derive might not point to the same item. You're best working with an array if you want to keep order. – Fogmeister Jan 15 '16 at 14:48
  • 1
    Absolutely possible, as you've already defined the order the only thing left for you to do is to save it at any ordered collection and use as you like. Of course it will also be important to keep two collections in sync which is error prone, so you might want to re-think the data structure and have what is now the keys to be simple properties of your objects stored at a single ordered collection. – A-Live Jan 15 '16 at 14:51
  • ... but a dictionary has unique keys, so instead of remembering an index, you can just remember a key in the dictionary. And the built-in iterator will give you key-value pairs, so it is easy to remember the one key that you are interested in. – gnasher729 Jan 15 '16 at 14:51
  • http://stackoverflow.com/a/27870433/2303865 – Leo Dabus Jan 15 '16 at 15:21
  • Hi @A-Live - how would I save it as an ordered collection? – richc Jan 15 '16 at 15:46
  • Create an array of strings and add all the keys of the dictionary. Sort the array any way you like. – gnasher729 Jan 15 '16 at 15:49

1 Answers1

0

In your example, your keys happen to be added in alphanumeric order. This could be fortuitous but if you meant to get the data in key sorted order, that is not the same request as creation order and it would be easy to do:

for (key,wordlist) in lists.sort({$0.0 < $1.0})
{
  // you will be getting the dictionary entries in key order
}

// trickier to access by index though
let aKey      = lists.keys.sort()[2]
let aWordList = lists[aKey]
// but it lets you get the wordlist from the key
let S1L3Words  = lists["Set 1: List 3"]

On the other hand, if you're meaning to ONLY use a creation order, and do not need to access the elements by their keys, you could declare your structure as an array of tuples:

 let lists: [(String, [String])] =
            [
             ("Set 1: List 1", string1),
             ("Set 1: List 2", string2),
             ("Set 1: List 3", string3)
            ]

 // your for loop will get them in the same order

 for (key,wordlist) in lists 
 {
    // array order, no matter what the key values are
 }
 // also accessible directly by index
 let (aKey, aWordList) = lists[2] // ("Set 1: List 3", ["made", "came", "same"])

And finally, if you don't need keys at all, you can just make it an array of arrays:

 let lists: [[String]] = [ string1 , string2 , string3 ]
 for (key,wordlist) in lists 
 {
    // array order
 }
 // also accessible directly by index
 let aWordList = lists[2] // ["made", "came", "same"]
Alain T.
  • 40,517
  • 4
  • 31
  • 51