Convert Parse.com json array into Array with swift - arrays

Can someone please help me with this. I saved my data into Parse.com into column with type array (example: ["11:30","12:45,"13:02"], just some list of some times as string). I have tried to get this data with swift:
var take: NSMutableArray!
var query = PFQuery(className: "test")
query.getObjectInBackgroundWithId("QZ6Y8Oljc5"){
(testData: PFObject!, error: NSError!) -> Void in
if (error == nil){
take = testData["workday"]
println(take)
}
else{
println(error)
}
}
the problem is that i get only json array type:
(
"11:30",
"12:45,
"13:02"
)
How can I convert it into NSArray so it could be like:
var myArray = ["11:30","12:45,"13:02"]
Thank you for any suggestions because I tried every method I found here, but without any results.

The problem with JSON data is that it is it's own array that has to be sifted and groomed. normally people would end up using huge nested IF statements which ends up looking messy. Luckily, someone created a code that sifts through JSON data and gives you back usable types (Int, Arrays, Strings) by use of a massive switch table.
https://github.com/SwiftyJSON/SwiftyJSON
Look it up, it should help. Once you have it implemented you can call it by typing..
let json = JSON(Data : JSONData)
then to sift through, you use substrings.. (depending on the data, you match it with a string or int)
let firstIndex = json["workday"]
//Int
let firstIndexOfWorkDay = json["workday"][0]
//String
let firstIndexOfWorkDay = json["workday"]["time"]
and so on... however, you will need to cast it once you singled out the data
let firstIndexOfWorkDay = json["workday"][0].valueOfFloat
//printing it would give 11:30
although personally I use ".description" .. since sometimes when I sift through all the array, its a mix of types.
let firstIndexOfWorkDay = json["workday"][0].description
println(firstIndexOfWorkDay)
//would literally give "11:30" including the quotation marks
then I use string methods to trim the quotations then cast it to whatever type I need. But it's up to your creativity once you figure out how it works

Related

Get formatted list of values from array in swift

im making sort of food delivery app with some backend functional, and now im struggling with getting elements of array as formatted order strings
guard
let defaults = UserDefaults.standard.data(forKey: "itemlist"),
let savedItems = try? JSONDecoder().decode([Order].self, from: defaults)
else {
return
}
let dictionary = savedItems.compactMap({ ($0.name!, $0.price!) })
let dishNames = dict.joined(separator: ",") //error
let order = "Заказ: \(dictionary)"
print(order)
result im getting:
[("Пепперони", "45см/500р."), ("Деревенская", "45см/520р.")]
what i want:
Пепперони 45см/500р. Деревенская 45см/520р.
i could do that easily in php, but im not finding analogues in swift, might anyone help me?

I want to filter array

I got two arrays from API call,
One is nameArray - which contains recipe names ( menuNameArray = ["pohe","bread","cheese chilli toast"]
And another array - which contains prices of those recipes (menuPriceArray = ["10", "40", "120"].
I have got theses two arrays from API call.
I am displaying both the arrays on the table view & I am searching through the menuNamesArray because I want to search by recipe names.
I am getting recipe names by searching those from menuNameArray. Now I want menuPriceArray to get updated also according to searched menuName Array.
means if I search for "bread" then I must get price value as "40" and accordingly for other names also.
How should I perform such filtering on the second array?
My code Snippet -
//MARK: UISearch result update delegate
func updateSearchResults(for searchController: UISearchController) {
// here arrFilter is the resulting array to sotre searched items from menuNamesArray
arrFilter.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (menuNamesArray as NSArray).filtered(using: searchPredicate)
let result = menuPriceArray.firstIndex(of: array.startIndex)
arrFilter = array as! [String]
self.tblSearch.reloadData()
//here now I got the searched menu names, Now I want prices for searched menu names from menuPrice Array..
}
Never use multiple arrays as data source.
Swift is an object oriented language. Take advantage of it.
Create a struct
struct Menu {
let name : String
let price : Double
}
and a data source array
var menues = [Menu]()
Filter the array by name and get the price, pretty easy and straightforward
if let foundMenu = menues.filter(where: {$0.name == "bread"}) {
print(foundMenu.price)
}
You can merge the two arrays into one array of dictionary elements.

Reading data from cvs file and converting data into multidimensional array in Swift

I'm new to Swift. I can read data (many rows and columns of names and mailing addresses) from csv file format. I have several of these files, so I created a function just to read the files and extract the data into a multidimensional array(s) - names, addresses, city, state, country. I read each of the lines from the file and try to append it to multidimensional array but I get errors - either index out of range or file type mismatch. What's the best way to enable this. See code below.
func getMailing(fileName: String) -> ([[String]])? {
let totalList = 243
var tempList: [String] = []
var arrayList = [[String]]()
guard let path = Bundle.main.url(forResource: fileName, withExtension: "csv") else {
print("File Error")
arrayList = [[""]]
return (arrayList)
}
do {
// get mailing data from file
let content = try String(contentsOf:path, encoding: String.Encoding.utf8)
// separate each line entry
tempList = content.components(separatedBy: "\r\n")
for index in 0...totalList - 1 {
// get each line from list and post into an array
let singleLine = tempList[index].components(separatedBy: ",").dropFirst().prefix(5)
// store each line data into into a multidimensional array for easy retrieval
arrayList[index].append(singleLine)
}
}
return (arrayList)
} catch {
print("File Error")
arrayList = [[""]]
return (arrayList)
}
}
Based on the code you've shown, it looks like you're trying to change the values of two different empty arrays 243 times. You have a loop setup to iterate based on your totalList property, but where you got that value, I have no idea. It would be wise to determine that value programmatically if you can.
You're setting both tempList and arrayList as empty arrays:
var tempList: [String] = []
var arrayList = [[String]]()
But then you're going through a loop and trying to change the value of an entry that doesn't even exist, hence your index out of range error. You need to first add something to both these arrays, because right now they are empty. It's probably crashing the first time through the loop when you try to set singleLine to tempList[index].components(separatedBy: ",").dropFirst().prefix(5), because you're saying tempList[0].components(separatedBy: ",").dropFirst().prefix(5), while there isn't an entry for tempList at index 0 because it's still empty! If you're going to loop through an array, it's always wise to do it based on the count of the array, or at least a quick fix when you need to use an index from two different arrays:
// Get the maximum times you can iterate based on the lowest count from each array
let maxLoop = min(tempList.count - 1, arrayList.count - 1)
for index in 0...maxLoop {
// get each line from list and post into an array
let singleLine = tempList[index].components(separatedBy: ",").dropFirst().prefix(5)
// store each line data into into a multidimensional array for easy retrieval
arrayList[index].append(singleLine)
}
Now that little chunk of code above won't even go through the loop once, because both arrays are still empty. You need to somewhere take your mailing data and parse it so that you can populate tempList and arrayList

PFObject Array Sort

I'm using Parse and I have an array of PFObjects called "scorecardData". Each PFObject has a "score" property that is of type Int. I'm trying to sort my array by "score" but I'm getting the following error: "Binary operator '<' cannot be applied to two 'AnyObject?' operands". I'm not sure what I'm doing wrong here. I also tried down casting the objectForKey("score") as! Int but its not letting me do this. Any suggestions? Thanks in advance.
var scorecardData = [PFObject]()
scorecardData.sortInPlace({$0.objectForKey("score") < $1.objectForKey("score")})
You declared scorecardData variable as Array of PFObject. Why are you trying access PFObject property using objectForKey: reserved? Anyway I am not parse expert. But if you declared your array as [PFObject] you can use:
scorecardData.sortInPlace({$0.score < $1.score})
But this won't work unless you subclass PFObject for a more native object-oriented class structure. If you do that remember also to specify:
var scorecardData = [YOUR_NEW_CLASS]()
I strongly recommend subclassing PFObject to make use of all swift type-safe goodies.
But if you want to keep your data structure you can use:
scorecardData.sortInPlace({($0["score"] as! Int) < ($1["score"] as! Int)})
Keep in mind that it's dangerous, and in future avoid it.
If you want to Sort your array of PFOject... You can do this
extension Array where Element:PFObject {
func sort() -> [PFObject] {
return sort { (first, second) -> Bool in
let firstDate = first.objectForKey("time") as! NSDate//objectForKey(Constants.Parse.Fields.User.fullName) as? String
let secondDate = second.objectForKey("time") as! NSDate//objectForKey(Constants.Parse.Fields.User.fullName) as? String
return firstDate.compare(secondDate) == .OrderedAscending
}
}
}
Have you tried doing this?
var query = PFQuery(className:"ScoreCard")
// Sorts the results in ascending order by the score field
query.orderByDescending("score")
query.findObjectsInBackgroundWithBlock {

Convert [String]? to String in Swift

For my project, I extracted tweets from a CSV file in Swift. Problem is now all tweets are parsed as one element in an array, separated by ",".
let tweetsOfColumns = columns["tweet"]
let seperatedColumns = tweetsOfColumns.componentsSeparatedByString(",")
Error message: '[String]?' does not have a member named
'componentsSeparatedByString'.
I checked if tweetsOfColumns contains multiple elements, but it doesn't allow me to subscript with tweetsOfColumns[index].
Looking at the link you reference, columns["tweets"] is going to give you back an array of the values from the "tweets" column, so it's what you need already, there's no additional comma's to split things on, you just need:
let seperatedColumns = columns["tweet"]
to have an array containing the tweet column for each row.
When you try to get an element from a dictionary, like
columns["tweet"]
it will give you back an optional, because if there is nothing associated with the key, it gives you back nil (None), otherwise the value wrapped in an optional (Some(data)).
So you have to unwrap the optional for example:
columns["tweet"]!
You have to either use the optional ? to access the string:
let seperatedColumns = tweetsOfColumns?.componentsSeparatedByString(",")
But you should unwrap it:
if let unwrappedTweets = tweetsOfColumns?.componentsSeparatedByString(","){
let seperatedColumns = unwrappedTweets
}
The problem is probably that you'll get an optional back, which you have to unwrap. And the easiest and most elegant is to use the if-let unwrapper.
if let tweetsOfColumns = columns["tweet"] {
let seperatedColumns = tweetsOfColumns.componentsSeparatedByString(",")
// do something with the seperatedColumns
}
Based on David's question and the OP's response in the OP comments, you can use map on the Array returned by columns["tweet"]. Please post actual data/code in the future.
let columns = [
"tweet":["handleX,tag1,tag2,textA,textB",
"handleY,tag1,tag2,textC,textD"]]
var chunk = [[String]]()
if columns["tweet"] != nil {
chunk = columns["tweet"]!.map {
return $0.componentsSeparatedByString(",")
}
}

Resources