How to filter inner arrays from multi-dimensional array
Asked Answered
P

3

5

I am trying to pull out variables (safety_rating_id, score etc.) from an array (called array) based on the submission_id using the swift library Dollar (https://github.com/ankurp/Dollar)'s find method so that I can later make a POST request (Eventually, I hope to be able to replace the hardcoded values in my parameter with the pulled array variables) with them but my results from find all return nil.

These are the inner arrays I want where the submission_id is 27 from this array https://codeshare.io/zr1pw (lines 22- 36):

{
 "submission_id" : "27",
 "name" : "Equipment",
 "task_id" : "37",
 "points" : "10",
 "safety_rating_id" : 105,
 "score" : "9"
}, {
 "submission_id" : "27",
 "name" : "Emergency Equipment",
 "task_id" : "37",
 "points" : "10",
 "safety_rating_id" : 106,
"score" : "9"
}

Code:

  var array: [JSON] = []   
  func submitScore(onCompletion: () -> (), onError: ((NSError) -> ())? = nil) {

    guard let endPoint = Data.sharedInstance.submitScoreEndpoint
        else { print("Empty endpoint"); return }

    let user = Users()

    let test = $.find(self.array, callback: { $0 == 27 })
    print(test)

    let Auth_header = [
        "Authorization" : user.token,
        ]

    let parameters: [String:Array<[String:Int]>] = [
        "ratings" : [
            [
                "safety_rating_id" : 105,
                "schedule_job_id" : 18,
                "score" : 9,
                "submission_id" : 27
            ],
            [
                "safety_rating_id" : 106,
                "schedule_job_id" : 18,
                "score" : 10,
                "submission_id" : 27
            ]
        ]
    ]


Alamofire.request(.POST, endPoint, headers: Auth_header, parameters: parameters, encoding: .JSON)
        .validate()
        .responseJSON {
        response in

        switch response.result {
        case .Success(let data):
            let json = JSON(data)
            print(json)
            onCompletion()
        case .Failure(let error):
            print("Request failed with error: \(error)")
            onError?(error)
        }

    }

}

UPDATE

I'm able to obtain the array with submission_id 27 BUT I want to remove name and task_id from the two submission_id : 27 arrays AND add an schedule_job_id that I got from elsewhere.

I've tried using a for in loop to create my own array from the variables that I want but I keep getting a nil crash. This is what the new array looks like https://codeshare.io/3VJSo

for in loop error

Eventually I want to do a "ratings" : [chosenArray]

Piracy answered 31/5, 2016 at 3:33 Comment(3)
Why are you calling .validate() twice?Aragonite
oh I didnt notice that thanks for pointing outPiracy
you have another similar question that I have answered: #37541189Ctenophore
G
3

So what gets passed inside of the callback is each element in the array so you will get passed the dictionary object. So if you want to find a specific item in the array you should do

let test = $.find(array) { $0["submission_id"]! == "27" }

If you want all elements in array that have submission id as 27 then use filter

let test = array.filter { $0["submission_id"]! == "27" }

To remove properties from a dictionary object you need to call removeValueForKey method on each item on the array.

let jsonWithMySubmissionId = self.array.filter ({ $0["submission_id"]! == 27 })
for json in jsonWithMySubmissionId {
  json.removeValueForKey("name")
  json.removeValueForKey("task_id")
  ...
}
Gavrilla answered 6/6, 2016 at 21:50 Comment(0)
G
2

I think you are using $ wrong. When you call $.find on self.array the array contains JSON objects, not sure what the object exactly is, but I assume it's Dictionary. So I think you should do something like:

let jsonWithMySubmissionId = self.array.filter ({ $0["submission_id"]! == 27 }).first

Then, I would avoid that force unwrap on the dictionary. It was just for you to understand my point in one line of code.

Edit:

Then you can iterate over the array and extract your fields like this:

let jsonWithMySubmissionId = self.array.filter ({ $0["submission_id"]! == 27 })
for json in jsonWithMySubmissionId {
  json["name"] = nil
  json["task_id"] = nil
  ...
}
Gruber answered 2/6, 2016 at 17:22 Comment(2)
Hi do you know how I can remove the name and task_id from each of the arrays generated (see updated post)Piracy
See my edit on the original post, if it solved your problem please consider accepting that answerGruber
S
2

Your dic in your for loop must be type of NSMutableDictionary. Because you can't manipulate NSDictionary.

Second thing there is no method like removeValueForKey.

You should use removeObjectForKey or removeObjectsForKeys.

In removeObjectsForKeys you have to pass array of parameters (keys as parameter).

In removeObjectForKey you can pass one string (key) as parameter.

Spurgeon answered 8/6, 2016 at 12:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.