title: Sort array of custom objects depending on dynamic criterias
body: <p>Say we have the following Object, Priority &amp; Requirement objects:</p>
  <pre><code>enum Priority: CaseIterable {
      case priorityA = &quot;priority_a&quot;
      case priorityB = &quot;priority_b&quot;
      case priorityC = &quot;priority_c&quot;
      case priorityD = &quot;priority_d&quot;
      case priorityE = &quot;priority_e&quot;
      case priorityF = &quot;priority_f&quot;
      case priorityG = &quot;priority_g&quot;
      ... 
  
      var weight: Int {
          switch self {
              ...
          }
      }
  }
  
  struct Object {
      let name: String
      let priorities: [Priority: Int]
  }
  
  enum RequirementBaseValue {
      case any
      case minimum(Int)
      case maximum(Int)
  }
  
  struct Requirement {
      let priority: Priority
      let baseValue: RequirementBaseValue
  }
  </code></pre>
  <p>An example:</p>
  <pre><code>let requirementA = Requirement(priority: .priorityB, baseValue: .any)
  let requirementB = Requirement(priority: .priorityC, baseValue: .minimum(100))
  let requirements = [requirementA, requirementB]
  
  let aPriorities =  [..., .priorityB: 0, .priorityC: 0, ... ]
  let objectA = Object(name: &quot;object_a&quot;, priorities: aPriorities)
  
  let bPriorities = [..., .priorityB: 950, .priorityC: 210, ... ]
  let objectB = Object(name: &quot;object_b&quot;, priorities: bPriorities)
  
  let cPriorities = [..., .priorityB: 950, .priorityC: 300, ... ]
  let objectC = Object(name: &quot;object_c&quot;, priorities: cPriorities)
  
  let dPriorities = [..., .priorityB: 250, .priorityC: 101,  ... ]
  let objectD = Object(name: &quot;object_d&quot;, priorities: dPriorities)
  
  let objects = [objectA, objectB, objectC, objectD]
  </code></pre>
  <p>The goal is to sort these objects:</p>
  <pre><code>let sortedObjects = objects.sorted(by: { ... })
  </code></pre>
  <p>For example, considering the weights of each priority is equal to 1, for the example above we would have:</p>
  <pre><code>print(sortedObjects)
  // [objectC, objectB, objectD, objectA]
  </code></pre>
  <p>And a few details about how the sorting should be performed:</p>
  <ul>
  <li>If the requirement <code>baseValue</code> is set to <code>any</code>: the higher the <code>resultValue</code> the earlier it should appear in the sorted array.</li>
  <li>If the requirement value is either set to <code>minimum(Int)</code> or <code>maximum(Int)</code>: if the priority doesn't match the condition, the object should be filtered out from the array, otherwise the higher the <code>resultValue</code> the earlier it should appear in the sorted array.</li>
  <li>If an object's priorities dictionary doesn't contain a specific priority, we consider the <code>baseValue</code> for this priority to be equal to 0.</li>
  <li>The <code>resultValue</code> is obtained by multipying the weight property of a priority by the <code>baseValue</code> of the priority.</li>
  <li>Each object will usually have between 80 to 200 priorities (maximum will be n=<code>Priority.allCases.count</code>).</li>
  <li>The objects array will usually have between 3000 to 5000 elements so performance will be important.</li>
  </ul>
  <p>I was thinking of doing something like this:</p>
  <pre><code>let sortedObjects = objects.sorted(by: { object in
     for requirement in requirements {
         let baseValue = object.priorities[requirement.priority] ?? 0
         let weight = requirement.priority.weight
         let resultValue = baseValue * weight
         ...
     } 
     return ...
  }
  </code></pre>
  <p>But then I'm not sure how to return the boolean because there are multiple requirements &amp; priorities for each object, and it's not just an AND or OR condition, but more of an else-if situation.</p>
  <p>Thank you for your help!</p>