Search through a large json file for a particular key value pair

Tyler Rolfe Source

I'm trying to figure out the best way to search through a large json file in Swift 2. The json file looks something like this:

        "Name": "Tom",
        "Job": "Plumber"
        "Name": "Bill",
        "Job": "Electrician"

So essentially all the keys are the same in the dictionaries but the pairs are different(or could be different).

I'm trying to find a value that is equal to in this case "Bill" or "Tom" but I don't know what index these individuals are in in the array.

I'm currently using an incremental for loop to increase the index of the array by one and inside the for loop use an if statement to see if the key: "Name" has a pair that is == "Bill" or "Tom" or whoever.

The code I have works but since the json file is incredibly long it takes forever to parse the data and get a result. Is there a faster way to do this? I'm not sure if it's worth mentioning but I am using SwiftyJSON and Alamofire in the project.




answered 2 years ago Tom Harrington #1

You can simplify your code, but reducing the amount of work done isn't so simple. If you have a large, unordered list, you'll need to scan through it until you find a match. Each entry requires a string comparison, which is slow. If the array were sorted, you could use a binary search to find the answer more quickly. So if you expect that you'll need to search this list frequently, it might be a good idea to start by sorting it. If your list isn't sorted, your requirements fundamentally require a lot of work.

Simplifying the code would look something like:

// Assuming the data is in an array named "people":
let predicate = NSPredicate(format: "Name = %@", "Bill")
let results = people.filteredArrayUsingPredicate(predicate)

But this just means that searching through the list is done by the framework instead of by you.

Depending on what else your app is doing, you might want to consider saving this data in Core Data. It's optimized for operations like searching for a match. Not to mention that you wouldn't have to keep the entire list in memory.

answered 2 years ago Moritz #2

Using filter should be at least a little bit faster on a big array than an incremental For-In loop.

Swift array version:

let peopleNamedTom = arrayOfPeople.filter { $0["Name"] == "Tom" }

SwiftyJSON array version:

let peopleNamedTom = arrayOfPeople.filter { $1["Name"] == "Tom" }

If unfortunately it's not significantly faster in your case, I find it more convenient than a loop for this task anyway.

Also note that SwiftyJSON objects add overhead and are slower to iterate than native Swift collections. If your JSON model is simple, you may benefit from just using NSJSONSerialization with a Swift array instead of SwiftyJSON.

comments powered by Disqus