Как получить только последние значения для каждого уникального имени в массиве структур в Swift4? - PullRequest
0 голосов
/ 28 ноября 2018

Имеет следующую структуру.

    struct LastValue {
        var name: String
        var price: Int
    }

    var lastValue = [
        LastValue(name: "coffee", price: 100),
        LastValue(name: "coffee", price: 200),
        LastValue(name: "coffee", price: 150),
        LastValue(name: "coffee", price: 200),
        LastValue(name: "dessert", price: 500),
        LastValue(name: "dessert", price: 700),
        LastValue(name: "dessert", price: 600),
        LastValue(name: "dessert", price: 800)    
    ]

Мне нужны только последние значения каждого имени.Другими словами, другими словами, я хочу привести только последние значения кофе и пустыни.

lastValue является динамическим, и можно добавить другое значение.

Результат, который я хочу получить,:

LastValue(name: "coffee", price: 200),
LastValue(name: "dessert", price: 800)

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018
struct LastValue {
    let name: String
    let price: Int
}

var array = [
    LastValue(name: "coffee", price: 100),
    LastValue(name: "coffee", price: 200),
    LastValue(name: "coffee", price: 150),
    LastValue(name: "coffee", price: 200),
    LastValue(name: "dessert", price: 500),
    LastValue(name: "dessert", price: 700),
    LastValue(name: "dessert", price: 600),
    LastValue(name: "dessert", price: 800)
]

Решение 1

let lastValues = array.reduce([]) { (result, value) -> [LastValue] in
    var updatedResult = result
    updatedResult.removeAll(where: {$0.name == value.name})
    updatedResult.append(value)
    return updatedResult
}

for value in lastValues {
    print(value.name, value.price)
}

Решение 2

@ Евгений подход также кажется хорошим, хотяможет быть улучшен следующим образом.

let names: Set<String> = Set(array.map( {$0.name} ))

var lastValues: [LastValue] = []
for name in names {
    lastValues.append(lastValue.last(where: {$0.name == name})!)
}

for lastValue in lastValues {
    print(lastValue.name, lastValue.price)
}
print(lastValues)

Я думаю, что это занимает как минимум 1 + n проходов в массиве.(Один, чтобы найти уникальные имена в массиве, и n проходит, чтобы найти последнее для n имен. Я не знаю, как работает last(where:, но я предполагаю, что он проходит через массив каждый раз?)


Редактировать: Улучшен первый подход после комментариев @ Paulw11 .

0 голосов
/ 28 ноября 2018

Альтернативно с Dictionary(grouping:by:

let lastValue = [
    LastValue(name: "coffee", price: 100),
    LastValue(name: "coffee", price: 200),
    LastValue(name: "coffee", price: 150),
    LastValue(name: "coffee", price: 200),
    LastValue(name: "dessert", price: 500),
    LastValue(name: "dessert", price: 700),
    LastValue(name: "dessert", price: 600),
    LastValue(name: "dessert", price: 800)
]

let result = Dictionary(grouping: lastValue, by: {$0.name}).compactMap{$0.1.last}

// [{name "coffee", price 200}, {name "dessert", price 800}]
0 голосов
/ 28 ноября 2018
let lastCoffee = lastValue.last(where: { $0.name == "coffee" })
let lastDesert = lastValue.last(where: { $0.name == "dessert" })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...