0

I am trying to transform a string of the following format into an array (...of arrays, of floats!) in Swift 3:

"[173.0, 180.5],[173.0, 180.0],[174.0, 180.5],[174.0, 183.0]"

so that the output would be an array in this format:

[[173.0, 180.5, 173.0, 180.0],[174.0, 180.5, 174.0, 183.0]]

I am really new to Swift and struggling to find any String functions that will allow me to convert the data in this way. Any pointers on how I can do it would be awesome - thanks!

3
  • 1
    Enclose the string in square brackets and then interpret it as JSON ... Commented Dec 14, 2016 at 18:30
  • @Rosie where does that string come from? Commented Dec 15, 2016 at 1:29
  • @Rosie, also what's up with the output format? The input is 4 arrays of 2 elements each, the output is 2 arrays of 4 elements each? Commented Dec 15, 2016 at 1:31

3 Answers 3

1

As Martin said, you first want to first convert this from a string to an array. In Swift 3:

let string = "[173.0, 180.5],[173.0, 180.0],[174.0, 180.5],[174.0, 183.0]"
let jsonString = "[" + string + "]"

guard let data = jsonString.data(using: .utf8),
    let json = try? JSONSerialization.jsonObject(with: data),
    let numberPairs = json as? [[Double]] else {
        fatalError("string was not well-formed: \(string)")
}

You then want to combine these pairs of numbers together:

var combinedNumbers = [[Double]]()
var current: [Double]?
for numberPair in numberPairs {
    if current != nil {
        combinedNumbers.append(current! + numberPair)
        current = nil
    } else {
        current = numberPair
    }
}

// use `combinedNumbers` here

Clearly, you should use better variable names (perhaps something that suggests what these sets of numbers are), but hopefully this illustrates the idea.

Sign up to request clarification or add additional context in comments.

Comments

0

Swift 4

You can use Decodable:

let str = "[173.0, 180.5],[173.0, 180.0],[174.0, 180.5],[174.0, 183.0]"
let json = "[\(str)]".data(using: .utf8)!

let numbers = try JSONDecoder().decode([[Double]].self, from: json).flatMap { $0 }
let result = stride(from: 0, to: numbers.count, by: 4).map { startIndex -> [Double] in
    let endIndex = min(startIndex + 4, numbers.count)
    return Array(numbers[startIndex..<endIndex])
}

Swift 3

One option is to use the old-school NSScanner to extract the numbers from the string to a flat array, then build a 2 dimensional array off that:

let str = "[173.0, 180.5],[173.0, 180.0],[174.0, 180.5],[174.0, 183.0]"
let scanner = Scanner(string: str)
scanner.charactersToBeSkipped = CharacterSet(charactersIn: "[], ")

// Build the flat array
var numbers = [Double]()
while !scanner.isAtEnd {
    var d = 0.0
    if scanner.scanDouble(&d) {
        numbers.append(d)
    }
}

// Now the 2 dimensional array
let result = stride(from: 0, to: numbers.count, by: 4).map { startIndex -> [Double] in
    let endIndex = min(startIndex + 4, numbers.count)
    return Array(numbers[startIndex..<endIndex])
}

Comments

0

One option to convert the data types would be to develop a simple algorithm that will iterate through the string and analyze elements and square bracket delimiters, returning the appropriate conversion.

Below is the skeleton of what the fundamental components of such a function could look like. Included are some basic aspects of the conversion from string to array.

var str = "[173.0, 180.5], [173.0, 180.0],[174.0, 180.5],[174.0, 183.0]"

// Cast returns array ["[","1","7","3",".","0",",".......]
let array = Array(str.characters)

// Iterate through array
for char in array {

    if char == "[" || char == "]" {
        // Deal with array delimiters appropriately
    }

    ...

}

It might help to check out this similar problem.

NOTE: As Martin R mentioned, JSON interpretation may be a good method as well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.