Find the right value in an Array, or in an Array of Dictionaries

From time to time I discover a new way of coding something that significantly improves readability & minimizes how much I need to code. 

Here’s one of such latest discoveries. Typically to find a value in an array (or in an array of dictionaries) with a specific condition I would do a for loop with an if statement checking for the right value. This works great of course, but its a lot of code to do something that simple. 

Here’s a simple way to find a value in an array of dictionaries:

let matchingArticle = arrayOfItems.first(where: {$0.exampleKey == 3843})

 

We ask the arrayOfItems to give us the first value where the dictionary key exampleKey takes the value 3843. 

And if it’s only an array of int or string, for example, is even easier:

 let matchingArticle = arrayOfItems.first(where: {$0 == 859})

We simply ask the arrayOfItems to give us the first value where the its value equals 859. 

Note, in this code example we assume you will always have only up to 1 match. 

I’ve come to love this function and I think you will too. 

 

Questions / comments / suggestions? I’m at @MarcMasVi 

Marc

 

Sorting Multi Dimensional Array (Swift 3)

Hello all, 

This one I’ve found specially useful when working with Core Data fetched arrays. 

Let’s say that we want to sort the result of a fetch request based on the value of the field “gold”, we would therefore do the following:

let dwarfGoldBags = … //Contains the result of a fetch request with one of the fields named “gold” and being an integer.


 

We will now proceed to sort the array and store it in sortedGoldArray:

let sortedGoldArray = dwarfGoldBags.sorted { ($0.goldas Int) > ($1.goldas Int) } 

 

If instead of core data you have a multi-dimensional array it would be as easy as:

let sortArray = originalArray.sorted { ($0.[0] as Int) > ($1.[0] as Int) } 

 

In this case we’re comparing the values stored in the first value of the subArrays. 

Questions / comments? I’m at @MarcMasVi 

Marc

Easy Core Data CSV Exporter in Swift

A new app I’m working on has a Core Data back end and I wanted to implement a quick way to export all the entities into a CSV file and dump it into the Desktop. 

Here are the snippets to do it:

1. Make sure you get the NSObjects you want to export (in this case I use a function that will return an array with the fetched NSObjectSubclass Transaction)

   private func provideAllTransactions() -> Array<Transaction>{

        let fetchRequest = NSFetchRequest(entityName: “Transaction”)

        fetchRequest.sortDescriptors = [NSSortDescriptor(key: “date”, ascending: false), NSSortDescriptor(key: “concept”, ascending: true)]

        return try! managedObjectContext.executeFetchRequest(fetchRequest) as! Array<Transaction>

    }

2. Convert to text, properly separating by commas and lines

    private func convertTransactionsToCsvString(transactions: Array<Transaction>)->String{

        var result = “HEADER 1, HEADER 2, HEADER 3, \r”//Headers

        

        for transactionIterator in transactions{ //Data

            result = result + “\”” + (transactionIterator.accountItBelongsTo?.name)! + “\”” + “,”

            result = result + “\”” + ((transactionIterator.date)?.description)! ?? NSDate().description

            result = result + “\”” + “,” + “\”” + (transactionIterator.concept)! + “\””

            result = result + “\”” + “\r”

        }

        

        return result

    }

3. Save to a path 

    func exportAllToCsv() -> Bool{

        

        let contentsToWrite = convertTransactionsToCsvString(provideAllTransactions())

        

        //Select path

        let path = “/Users/USER_NAME/Desktop/csvTest.csv”

        //Try to save it

        do {

            try contentsToWrite.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding)

        }catch{

            print(“ERROR: Export could not be saved in %”, path)

        }

        

        return true

 

    }

Note that in this example the path is hardcoded to the desktop of the user named USER_NAME, you should have the user choose where he wants to save it or you can hardcode a location in your disk. 

If you would have a NSDictionary it would be almost the same but starting at point 2 with the dictionary results. 

Questions / comments? I’m at @MarcMasVi

Marc

 

PS. Here is how you would have the path be selected by the user:        

 

    privatefunc userToChooseAFileInModalPannel() -> String?{

        let pannel: NSOpenPanel = NSOpenPanel()

        pannel.canChooseDirectories = true

        pannel.canChooseFiles = false

        pannel.allowsMultipleSelection = false

        pannel.runModal()

        

        return pannel.URL?.path

    }

 then in point 3 you would do 

//Select path

        let path = userToChooseAFileInModalPannel() + “/test.csv”