'How to convert array to another array in Swift

I want to convert beforeDataSet to afterDataSet in Swift. Could you tell me how to convert it?

struct BeforeData {
    var value: Int
    var date: Date
}

struct AfterData {
    var sumValue: Int
    var dateString: String
}

let beforeDataSet = [
    BeforeData(value: 100, date: date1), // 2022-01-01 12:00
    BeforeData(value: 150, date: date2), // 2022-01-01 14:11
    BeforeData(value: 120, date: date3), // 2022-01-02 07:00
    BeforeData(value: 120, date: date4), // 2022-01-02 12:00
    BeforeData(value: 200, date: date5), // 2022-01-03 08:00
]

let afterDataSet = [
    AfterData(sumValue: 250, dateString: "2022/1/1"),
    AfterData(sumValue: 240, dateString: "2022/1/2"),
    AfterData(sumValue: 200, dateString: "2022/1/3"),
]


Solution 1:[1]

If you are grouping these for grouping these in the UI, I would suggest a few things:

  1. AfterData should use Date, not String.
  2. When you present this in the UI, use a user-friendly date formatter rather than the cryptic yyyy/MM/dd format. E.g., a dateStyle of .medium.
  3. I would use reduce to calculate the totals by day, sort to sort them, and map to create your custom objects.
  4. FWIW, using this pattern, you are no longer dependent upon the input data having already been sorted.

So, perhaps:

struct BeforeData {
    var value: Int
    var date: Date
}

struct AfterData {
    var sum: Int
    var date: Date    // note, not `String`
}

let iso = ISO8601DateFormatter()
let date1 = iso.date(from: "2022-01-01T12:00:00Z")!
let date2 = iso.date(from: "2022-01-01T14:11:00Z")!
let date3 = iso.date(from: "2022-01-02T07:00:00Z")!
let date4 = iso.date(from: "2022-01-02T12:00:00Z")!
let date5 = iso.date(from: "2022-01-03T08:00:00Z")!

let before = [
    BeforeData(value: 100, date: date1),
    BeforeData(value: 150, date: date2),
    BeforeData(value: 120, date: date3),
    BeforeData(value: 120, date: date4),
    BeforeData(value: 200, date: date5)
]

let calendar = Calendar.current

let grouped = before
    .reduce(into: [Date: Int]()) { dictionary, object in
        let day = calendar.startOfDay(for: object.date)
        dictionary[day, default: 0] += object.value
    }
    .sorted { $0.0 < $1.0 }
    .map { AfterData(sum: $0.value, date: $0.key) }

And then:

let formatter = DateFormatter()
formatter.dateStyle = .medium

for value in grouped {
    print(formatter.string(from: value.date), value.sum)
}

And a US user will see:

Jan 1, 2022 370
Jan 2, 2022 120
Jan 3, 2022 200

But a UK user will see:

1 Jan 2022 370
2 Jan 2022 120
3 Jan 2022 200

Then we are showing dates in the format with which the end-user is comfortable.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rob