1

Given this array of values:

let values = [
    ["2020-01-01", 1, 3, 2],
    ["2020-02-01", 10, 30, 20],
    ["2020-03-01", 100, 300, 200]
]

How can I convert it in something like this?:

public struct Point {
    var date: String
    var price: Double
}

let expectedResult: [[Point]] = [
    [Point(date: "2020-01-01", price: 1), Point(date: "2020-02-01", price: 10), Point(date: "2020-03-01", price: 100)],
    [Point(date: "2020-01-01", price: 3), Point(date: "2020-02-01", price: 30), Point(date: "2020-03-01", price: 300)],
    [Point(date: "2020-01-01", price: 2), Point(date: "2020-02-01", price: 20), Point(date: "2020-03-01", price: 200)]
]

I expect values to always have 1 String and a different number of Doubles, from that I need an array of Point for each of those Doubles.

I've tried different approaches with .map or nested for loops but I never get to the desired result or I end up with a very hard to read code.

3
  • A String is not a Date. You should use Date. And you should also be careful of using Double for currency, as it'll give you perhaps unexpected results. stackoverflow.com/questions/3730019/… Commented May 9, 2021 at 12:55
  • 1
    Yeah I'm not using either String or Double, I just put them here to keep the example simple, the strings in the example could as well be "A", "B", "C" Commented May 9, 2021 at 12:58
  • 1
    Okay good good, just checking. Commented May 9, 2021 at 13:06

2 Answers 2

1

you can do this:

import UIKit

let values = [
    ["2020-01-01", 1.0, 3.0, 2.0],
    ["2020-02-01", 10.0, 30.0, 20.0],
    ["2020-03-01", 100.0, 300.0, 200.0]
]

public struct Point {
    var date: String
    var price: Double
}

var expectedResult: [[Point]] = []

for i in 1..<values[0].count {
    var points: [Point] = []
    for j in 0..<values.count {
        points.append(Point(date: values[j][0] as! String, price: values[j][i] as! Double))
    }
    expectedResult.append(points)
}

print(expectedResult)
Sign up to request clarification or add additional context in comments.

1 Comment

Those explicit for loops can just be replaced by a simple map and flatMap.
0

The input is really quite suspicious ([Any] is never fun to work with, you should try to avoid it.), but all you need is two simple maps.

let values = [
    ["2020-01-01", 1, 3, 2],
    ["2020-02-01", 10, 30, 20],
    ["2020-03-01", 100, 300, 200]
]

public struct Point {
    var date: String
    var price: Double
}

let points: [[Point]] = values.map { pointData in
    let date = pointData.first! as! String // You REALLY should parse this into a `Date`.
    let prices = pointData.dropFirst()
    
    return prices.map { Point(date: date, price: Double($0 as! Int)) }
}

points.forEach { print($0) }

5 Comments

This doesn't give the expect result, for example the first array end up being: [Point(date: "2020-01-01", price: 1), Point(date: "2020-01-01", price: 3), Point(date: "2020-01-01", price: 2)] instead of [Point(date: "2020-01-01", price: 1), Point(date: "2020-02-01", price: 10), Point(date: "2020-03-01", price: 100)]
Sounds like you just need to transpose the result. stackoverflow.com/q/39889568/3141234
Now this is even more strange, the groupings you have look like this, imgur.com/a/7VDJT0b What's the pattern?
basically each array in values contains the points needed to make 3 charts. for example in: ["2020-01-01", 1, 3, 2] "2020-01-01" is the point in the X axis and 1 would be the point in the Y axis for the first chart, 3 and 2 are the Y points for other two charts with the same X axis value. That's why I need this to end up being 3 different arrays to make 3 different charts. It's way more complex then what it needed to be but I don't have a say in the way I get these values so I have to stick with this approach
Interesting. Welp, transposing will the do the job.

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.