There are two arrays - first one is about dates, and the second one shows spendings, being made that day:
var arrayOfDates = [01.07, 01.07, 03.07, 04.07, 05.07, 05.07, 05.07]
var arrayofCosts = [3, 8, 2, 2, 8, 6, 9]
I want to filter the arrayOfDates
for unique elements. And in the second array show the highest-value spending for each day.
So the result should be:
var arrayOfDatesModifed = [01.07, 3.07, 04.07, 05.07]
var arrayofNumbersModifed = [8, 2, 2, 9]
So this idea consists of 3 phases:
- Filter
arrayOfDates
for unique elements - For each unique date find corresponding item(s) in
arrayofCosts
- Find the biggest value in
arrayofCosts
for each date
Though each of this tasks individually may be simple, I cant figure it out how to accomplish them altogether. Your help will be very much appreciated
CodePudding user response:
I agree with those with comments. Working with individual arrays is going to be a real pain.
Let's implement a struct to hold our data.
struct Entry: CustomStringConvertible {
let date: Double
let cost: Int
var description: String {
"(\(date), \(cost))"
}
}
These are just the entries from your example:
let entries: [Entry] = [
.init(date: 01.07, cost: 3),
.init(date: 01.07, cost: 8),
.init(date: 03.07, cost: 2),
.init(date: 04.07, cost: 2),
.init(date: 05.07, cost: 8),
.init(date: 05.07, cost: 6),
.init(date: 05.07, cost: 9),
]
The first thing I would do is group all entries by date:
let groupedEntries = Dictionary(grouping: entries) { $0.date }
print(groupedEntries)
Which gives us an unordered Dictionary where the key is the date and the value is an array of entries having the same date:
[1.07: [(1.07, 3), (1.07, 8)], 5.07: [(5.07, 8), (5.07, 6), (5.07, 9)], 3.07: [(3.07, 2)], 4.07: [(4.07, 2)]]
The next thing I would do is extract the entry with the max cost in each group and discard the entries with the lower costs. We don't need those. So now we have an array of entries where the low cost elements have been filtered out.
let uniqueDateMaxEntry = groupedEntries.compactMap { _, entries in
return entries.max(by: { $0.cost < $1.cost })
}
print(uniqueDateMaxEntry)
This gives us:
[(1.07, 8), (4.07, 2), (5.07, 9), (3.07, 2)]
As you can see, the array is not sorted by the date. So we can do that now
let sortedUniqueDateMaxEntry = uniqueDateMaxEntry
.sorted { $0.date < $1.date }
print(sortedUniqueDateMaxEntry)
And finally that gives us:
[(1.07, 8), (3.07, 2), (4.07, 2), (5.07, 9)]