Home > OS >  Filter array, according to the filter of another array
Filter array, according to the filter of another array

Time:07-30

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:

  1. Filter arrayOfDates for unique elements
  2. For each unique date find corresponding item(s) in arrayofCosts
  3. 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)]
  • Related