Home > database >  Swift: Group duplicate array elements into new array
Swift: Group duplicate array elements into new array

Time:04-12

I have an Order object as follows:

struct Order {
    let id: Int
    let item: String
    let price: Int
}

These are grouped in an, however sometimes there are duplicate IDs and I need these to be grouped into their own array of Order duplicate objects. So essentially at the moment I have [Order] and I need to convert this into [[Order]] where all duplicates will be grouped together, and where there are no duplicates they will simply be on their own in an array.

So for example, imagine I have the following array of orders:

[Order(id: 123, item: "Test item1", price: 1)
Order(id: 345, item: "Test item2", price: 1)
Order(id: 678, item: "Test item3", price: 1)
Order(id: 123, item: "Test item1", price: 1)]

This needs to be converted to:

[[Order(id: 123, item: "Test item1", price: 1), Order(id: 123, item: "Test item1", price: 1)],
[Order(id: 345, item: "Test item2", price: 1)],
[Order(id: 678, item: "Test item3", price: 1)]]

I have been playing around with a dictionary and have so far come up with the following:

let dictionary = Dictionary(grouping: orders, by: { (element: Order) in
    return element.id
})

This returns the following type:

[Int : [Order]]

Which is close, but I don't really want them in a dictionary like this. I just need to be able to get an [[Order]] array that I can loop through for use in my UI.

CodePudding user response:

All you have to do is to use .values on the dictionary you have created and you have your array,

let values = Dictionary(grouping: orders, by: \.id).values

CodePudding user response:

This somewhat should do the trick, not the best solution but should be enough to get it working.

var orders = [[Order]]()

for order in orders {
    if let index = orders.firstIndex(where: { $0.id == order.id }) {
        // We have this order id already let's append another duplicate
        orders[index].append(order)
    } else {
        // We don't have this order id, create a new array
        orders.append([order])
    }
}

  • Related