0

I have an issue please, i will be so glad to get help on this, i sent a post request to an API server, i got the response back successfully and filtered out for the last element in the array using "array.last" The results for this is shown below, i was surprised to find out that the last element looked like an array again on it's own, i will like to filter this further and get results based on the the element with the highest probability. For example, inside the last element of my array, i have the two below.

ClarifaiModel(name: "feminine", probability: 0.8970829) ClarifaiModel(name: "masculine", probability: 0.10291709)

The one with the highest probability is ClarifaiModel(name: "feminine", probability: 0.8970829). I hope this makes sense, i can always answer further questions. Thanks.

The last element in my array of elements is below,

ClarifaiModel(name: "39", probability: 0.6835152)
ClarifaiModel(name: "38", probability: 0.6712693)
ClarifaiModel(name: "37", probability: 0.65020597)
ClarifaiModel(name: "36", probability: 0.6027025)
ClarifaiModel(name: "40", probability: 0.5968272)
ClarifaiModel(name: "41", probability: 0.50408536)
ClarifaiModel(name: "35", probability: 0.46325612)
ClarifaiModel(name: "42", probability: 0.39715457)
ClarifaiModel(name: "34", probability: 0.3904736)
ClarifaiModel(name: "33", probability: 0.29972908)
ClarifaiModel(name: "43", probability: 0.2892449)
ClarifaiModel(name: "44", probability: 0.2792564)
ClarifaiModel(name: "45", probability: 0.17198724)
ClarifaiModel(name: "32", probability: 0.16969433)
ClarifaiModel(name: "31", probability: 0.16112417)
ClarifaiModel(name: "30", probability: 0.14761531)
ClarifaiModel(name: "29", probability: 0.13462797)
ClarifaiModel(name: "28", probability: 0.119995646)
ClarifaiModel(name: "46", probability: 0.108111665)
ClarifaiModel(name: "27", probability: 0.103014976)
ClarifaiModel(name: "feminine", probability: 0.8970829)
ClarifaiModel(name: "masculine", probability: 0.10291709)
ClarifaiModel(name: "asian", probability: 0.9898949)
ClarifaiModel(name: "native hawaiian or pacific islander", probability: 0.011381255)
ClarifaiModel(name: "hispanic, latino, or spanish origin", probability: 0.0006249249)
ClarifaiModel(name: "white", probability: 0.00053802715)
ClarifaiModel(name: "american indian or alaska native", probability: 0.0003932913)
ClarifaiModel(name: "black or african american", probability: 0.00021348728)
ClarifaiModel(name: "middle eastern or north african", probability: 3.989372e-05)

My ClarifaiModel Class is shown below,

import Foundation

struct ClarifaiModel {
    let name: String
    let probability: Double
}


extension ClarifaiModel: Comparable {
    static func < (lhs: ClarifaiModel, rhs: ClarifaiModel) -> Bool {
        lhs.probability < rhs.probability
    }
}

Part of my view controller class is shown below where i got my data from API and tried to filter out what i need from my array.

 guard let data = data else { return }

                  // And finally, we are going to parse the JSON data and cast it as a dictionary so we can pull out the fact text to display it.
                  do {
                      guard let clarifaiData = try JSONSerialization.jsonObject(with: data, options: [.allowFragments]) as? [String: Any] else { return }
                      guard let outputs = clarifaiData["outputs"] as? [[String: Any]] else { return }
                      guard let outputsData = outputs[0]["data"] as? [String: Any] else { return }
                      guard let regions = outputsData["regions"] as? [[String: Any]] else { return }
                      guard let regionsData = regions[0]["data"] as? [String: Any] else { return }
                      guard let concepts = regionsData["concepts"] as? [[String: Any]] else { return }
                    //  print(concepts)



                      for concept in concepts {

                          let name = concept["name"] as? String ?? ""
                          let certainty = concept["value"] as? Double ?? 0.0000

                          let newModel = ClarifaiModel(name: name, probability: certainty)
                        self.clarifaiModel.append(newModel)
                    //  let a =  self.clarifaiModel.last!
                        let array = [
                            self.clarifaiModel
                        ]
                        let max = array.max()
                        print(max!)


                      }

I get an error of 'Referencing instance method 'max()' on 'Sequence' requires that '[ClarifaiModel]' conform to 'Comparable'' I have never used this comparable protocol before and do not understand it at all.Please help

Tony_Kara
  • 31
  • 8
  • 1
    Your question is unclear. What exactly do you need help with? Do you need to filter an array to find the element with max probability? And the code you've shown doesn't make a lot of sense either (was this supposed to be an array?). How is this related to `array.last`, or was this bit of info unrelated to your question? – New Dev Jun 08 '20 at 21:26
  • Are you trying to get the highest probability prediction from the array?? – Clarifai Support Jun 09 '20 at 17:39
  • Yes. exactly. i will like to have the highest probability if possible or at the very least, i will like to have the results displayed on your website for uploaded face image which gives results of a single Age, two gender with probability and multicultural appearance. The results i have as shown above is not usable for me. thanks – Tony_Kara Jun 10 '20 at 19:07

2 Answers2

0
extension ClarifaiModel: Comparable {
    static func < (lhs: ClarifaiModel, rhs: ClarifaiModel) -> Bool {
        lhs.probability < rhs.probability
    }
}

let array = [
    ClarifaiModel(name: "39", probability: 0.6835152),
    ClarifaiModel(name: "38", probability: 0.6712693),
    ClarifaiModel(name: "37", probability: 0.65020597),
    ClarifaiModel(name: "36", probability: 0.6027025)
]
let max = array.max()

if you have array of arrays you mentioned in comment:

let arrays = [array, array]
let maxx = arrays.flatMap({$0}).max()
farhad
  • 430
  • 2
  • 8
  • I did this and it came back with an error, "Referencing instance method 'max()' on 'Sequence' requires that '[ClarifaiModel]' conform to 'Comparable'". I have actually conform to Comparable and will show this in my further edits above. – Tony_Kara Jun 09 '20 at 09:41
  • if it says [ClarifaiModel] should conform then you have array of arrays try `arrays.flatMap({$0}).max()` instead – farhad Jun 09 '20 at 09:42
  • Please check the further edits i wrote above, please help, this is the only place i have issues. where do i place the arrays.flatMap({$0}).max() code. – Tony_Kara Jun 09 '20 at 09:48
  • replace `let array = [self.clarifaiModel]` with `let array = self.clarifaiModel` – farhad Jun 09 '20 at 12:44
  • I have actually done this and it still brings all the large response back. I have been trying to get only the neccessary results which i can set to a label in my viewcontroller, my aim is to filter out the results as shown in the actual API server below which is https://www.clarifai.com/models/demographics-image-recognition-model-c0c0ac362b03416da06ab3fa36fb58e3 – Tony_Kara Jun 09 '20 at 19:39
0
yourArray.sort(by: { $0.probability > $1.probability })
print(yourArray.first)
Chris
  • 7,579
  • 3
  • 18
  • 38