Home > Software design >  How to Sort the first dimension of a 2D Array Swift
How to Sort the first dimension of a 2D Array Swift

Time:04-12

Im trying to sort the columns of a CSV file,the contents of the CSV is provided in string

Beth,Charles,Danielle,Adam,Eric\n
17945,10091,10088,3907,10132\n
2,12,13,48,11

Converted String to 2D Array

[["Beth", "Charles", "Danielle", "Adam", "Eric"], ["17945", "10091", "10088", "3907", 
"10132"], ["2", "12", "13", "48", "11"]]

How can i sort the only the first dimension of the 2D array or the Names in the 2D Array and still keep the mappings of the other dimension, i don't know how to explain this properly, but i hope the details below will help you understand what i want to achieve.

Adam,Beth,Charles,Danielle,Eric\n
3907,17945,10091,10088,10132\n
48,2,12,13,11

I want to achieve this with the names sorted and the other values in the other arrays mapping to the names like below,

[["Adam", "Beth", "Charles", "Danielle", "Eric"], ["3907", "17945", "10091", "10088", 
"10132"], ["48", "2", "12", "13", "11"]]

Using this approach is not working but sorts the whole array

let sortedArray  = 2dArray.sorted(by: {($0[0] as! String) < ($1[0] as! String) })
[["3907", "17945", "10091", "10088", "10132"], ["48", "2", "12", "13", "11"], ["Adam", "Beth", "Charles", "Danielle", "Eric"]]

Below if the full code

var stringCSV = 
"Beth,Charles,Danielle,Adam,Eric\n17945
,10091,10088,3907,10132\n2,12,13,48,11";

var csvFormatted = [[String]]()

stringCSV.enumerateLines { line , _ in
var res = line.split(separator: ",",omittingEmptySubsequences: 
false).map{ String($0) }
for i in 0 ..< res.count {
    res[i] = res[i]
  }
    csvFormatted.append(res)
  
   }

   print(csvFormatted)
   let sortedArray  = csvFormatted.sorted(by: {($0[0] as! String) 
   <  ($1[0] as! String) })
   print(sortedArray)

CodePudding user response:

Using "associated" arrays always ends up being messy.

I would start by creating a struct to represent each object (You haven't said what the numbers are, so I have picked a couple of property names. I have also kept String as their type, but converting to Int is possibly better, depending on what the data actually represents).

struct Person {
   let name: String
   let id: String
   let age: String
}

Now you can combine the arrays and use that to build an array of these structs. Then you can sort by the name property.

    let properties = zip(sourceArray[1],sourceArray[2])
    let namesAndProperties = zip(sourceArray[0],properties)
 
    let structArray = namesAndProperties.map { (name,properties) in 
        return Person(name: name, id: properties.0, age: properties.1)
    }

    let sortedArray = structArray.sorted {
        return $0.name < $1.name
    }
  • Related