title: Sort Array of Struct Arrays [Array][Struct]
body: <p>I have a 3D array that is built via a an enumerated for loop that performs a background query of local SQL Lite table. 99% of the time everything is in order. 1% of the time things get a bit out of sequence.</p>
  
  <p>As the code to perform the background task is contained within a closer that has a completion handler I'm not sure why the sequence gets funny.  Below is how the structs and arrays are formed.</p>
  
  <p>I was thinking of sorting the array but cant get the syntax and not sure if this is the best approach? it feels like a work around.</p>
  
  <pre><code>struct CollectionStruct {
      var name : String
      var description : String
      var title : String
      var image : PFFile
      var id: String
  }
  
  var packArray : [CollectionStruct] = []
  var partArray : [CollectionStruct] = []
  var multiPartArray : [[CollectionStruct]] = []
  var tempPartArray : [[CollectionStruct]] = []
  
  override func viewDidLoad() {
      super.viewDidLoad()
  
      // Built the self.packArray here in simalr fashion to below.
      // Always in correct order as the query to build it is sorted
  
  
      // Now build the partArray for each packArray
  
      // access with
      // self.multiPartArray[0][0].name
  
      for (index, item) in  self.packArray.enumerated() {
  
          print(index, item)
  
          // is it the index that is out of sequence?
          self.packId = self.packArray[index].id
  
          BuildArray.buildArrayFromQuery(queryForCollection: "Part", selectedPackID: self.packId, delegateSender: "DownloadPart", completeBlock: { (result) in
  
              if result.isEmpty == false {
  
                  self.partArray = result
                  // this is how i was appending the result.  But it will occasionaly append the results in the wrong order.
                  // self.packArray[1], self.packArray[0].  Not sure if its because of the index from the enumeration or what??
  
                  // self.multiPartArray.append(self.partArray)
  
                  // this is where i was thinking of sorting the array ( or outside for loop ) this will do for not to test
                  // set it to a temp so it can be sorted...
                  self.tempPartArray.append(self.partArray)
  
                  // now sort it.. dont know wtf to do here cant see anything online
                  self.multiPartArray = self.tempPartArray.sorted(by: { ([CollectionStruct], [CollectionStruct]) -&gt; Bool in
                      &lt;#code#&gt;
                  })
  
              }
          })
      }
  }
  </code></pre>
  
  <p>I can not figure out the syntax for how to sort this.  In another location i have used the below code to sort a smaller struct array:</p>
  
  <pre><code>self.packArray = result.sorted {
      $0.name &lt; $1.name
  }
  </code></pre>
  
  <p>---- EDIT ---- </p>
  
  <p>The prompted code for the <code>.sorted</code> function is as shown below, where there is <code>[CollectionStruct], [CollectionStruct]</code> However The properties from my Struct ( <code>.name</code> ect ) are not available in the sort.</p>
  
  <pre><code>self.multiPartArray = self.tempPartArray.sorted(by: { ([CollectionStruct], [CollectionStruct]) -&gt; Bool in
       &lt;#code#&gt;
  })
  </code></pre>
  
  <p>The typical $0 &lt; $1 ect is not available either as i can not apply binary operators to 2 Structs??
  Ideally i can sort by the .name as this is a sequential identifier. So sort by </p>
  
  <pre><code>self.multiPartArray[0][0].name &lt; self.multiPartArray[0][1].name &lt; .... so on
  </code></pre>
  
  <p>This is a sample output of the data, when it is out of sequence, you can see that pk010 is coming after pk020, everything else is in sequence.</p>
  
  <pre><code>[[Proj.CollectionStruct(name: "pk000-01", description: "This is an intro session. ", title: "Session 1", image: &lt;PFFile: 0x7b91dff0&gt;, id: "JKE5K4xOQA"), Proj.CollectionStruct(name: "pk000-02", description: "This is a lot of text.", title: "Session 2", image: &lt;PFFile: 0x7b892a30&gt;, id: "ft4o3EWyxX"), Proj.CollectionStruct(name: "pk000-03", description: "This is session 3", title: "Session 3", image: &lt;PFFile: 0x7a6fa5f0&gt;, id: "jebz0c8Bq1"), Proj.CollectionStruct(name: "pk000-04", description: "This is a test", title: "Session 4", image: &lt;PFFile: 0x7b88e390&gt;, id: "E2rGHJMcR7"), Proj.CollectionStruct(name: "pk000-05", description: "This is a set", title: "Session 5", image: &lt;PFFile: 0x7b892320&gt;, id: "dkRAUEbdUb"), Proj.CollectionStruct(name: "pk000-06", description: "Test", title: "Session 6", image: &lt;PFFile: 0x7a6f68a0&gt;, id: "ODTJd3gIml")],
   [Proj.CollectionStruct(name: "pk020-01", description: "This is an intro session", title: "Session 1", image: &lt;PFFile: 0x7a6f7600&gt;, id: "6uG2cJGxrZ"), Proj.CollectionStruct(name: "pk020-02", description: "Session 2", title: "Session 2", image: &lt;PFFile: 0x7b878d60&gt;, id: "6T6r8e8dS3"), Proj.CollectionStruct(name: "pk020-03", description: "Session 3", title: "Session 3", image: &lt;PFFile: 0x7a7a0ff0&gt;, id: "2hDSALAG0a"), Proj.CollectionStruct(name: "pk020-04", description: "Session 4", title: "Session 4", image: &lt;PFFile: 0x7b910bd0&gt;, id: "vd0eBYb3gr"), Proj.CollectionStruct(name: "pk020-05", description: "Session 5", title: "Session 5", image: &lt;PFFile: 0x7b88f790&gt;, id: "MS8ece8dr8"), Proj.CollectionStruct(name: "pk020-06", description: "Session 6", title: "Session 6", image: &lt;PFFile: 0x7a7765c0&gt;, id: "aDfmH8bFKU"), Proj.CollectionStruct(name: "pk020-07", description: "Session 7", title: "Session 7", image: &lt;PFFile: 0x7b9eaf50&gt;, id: "obfW0pZsBH"), Proj.CollectionStruct(name: "pk020-08", description: "Session 8", title: "Session 8", image: &lt;PFFile: 0x7a783c20&gt;, id: "cVmEefiirT")],
   [Proj.CollectionStruct(name: "pk010-01", description: "This is an intro session", title: "Session 1", image: &lt;PFFile: 0x7a6f9b20&gt;, id: "BPtmDXvzDF"), Proj.CollectionStruct(name: "pk010-02", description: "Session 2", title: "Session 2", image: &lt;PFFile: 0x7a79ac00&gt;, id: "B3MAHoFEYs"), Proj.CollectionStruct(name: "pk010-03", description: "Session 3", title: "Session 3", image: &lt;PFFile: 0x7a627e40&gt;, id: "Yg6TxTuyHi"), Proj.CollectionStruct(name: "pk010-04", description: "Session 4", title: "Session 4", image: &lt;PFFile: 0x7a627f90&gt;, id: "XTRUoKVH9P"), Proj.CollectionStruct(name: "pk010-05", description: "Session 5", title: "Session 5", image: &lt;PFFile: 0x7a627b80&gt;, id: "eO9xS05qsW"), Proj.CollectionStruct(name: "pk010-06", description: "Session 6", title: "Session 6", image: &lt;PFFile: 0x7b879bd0&gt;, id: "ePZdmFnnoQ"), Proj.CollectionStruct(name: "pk010-07", description: "Session 7", title: "Session 7", image: &lt;PFFile: 0x7be58c50&gt;, id: "BO6HGa7w1R"), Proj.CollectionStruct(name: "pk010-08", description: "Session 8", title: "Session 8", image: &lt;PFFile: 0x7a69bd20&gt;, id: "dwIxpmD2y8")],
   [Proj.CollectionStruct(name: "pk030-01", description: "Session 3", title: "Session 3", image: &lt;PFFile: 0x7b87da60&gt;, id: "lU1rm5cnbb")]]
  </code></pre>
  
  <p>----- EDIT ----</p>
  
  <p>I still haven't been able to sort this but I've been playing with at least catching the error,  its not too graceful as its in another enumerated loop but its the best my brain has at the moment.</p>
  
  <pre><code>// add a group for the for enumeration check
  let insideGroup = DispatchGroup()
  
  for (index, item) in self.tempPartArray.enumerated() {
      insideGroup.enter()
      if index &gt;= 1 {
          // if the currentItem.name &gt; the previousItem.name
          if item[0].name &gt; self.tempPartArray[index - 1][0].name {
              print("The array is in sequence")
              insideGroup.leave()
  
          } else {
              print("the array is out of sequence")
  
              // exit gracefully
          }
      }
  }
  // the enumeration has finished you can set the variables
  insideGroup.notify(queue: .main) {
      self.multiPartArray = self.tempPartArray
  }
  </code></pre>
  
  <p>----- EDIT ----</p>
  
  <p>Even re-writing the queries to be synchronous tasks still returns data out of sequence as one query might take longer than another.</p>
  
  <p>I think what i need to do here is make the query part of an Operation with a axConcurrentOperationCount = 1</p>
  
  <p>That should force the results into sequence.</p>
  
  <p>Id still like to know how to sort this type of array though....</p>