Простой способ заменить элемент в массиве, если он существует, добавить его, если он не существует

По крайней мере, в Геккосе это возможно. Посмотрите здесь:

edit: Я не мог заставить это работать; похоже, что Гарет прав ...

0
задан Dávid Pásztor 20 March 2019 в 15:13
поделиться

2 ответа

Учитывая ваш вариант использования, в котором вы всегда проверяете [113].<prop> == newthing.<prop>, вы можете поднять это немного больше, добавив:

mutating func replaceOrAppend<Value>(_ item: Element, 
                                     firstMatchingKeyPath keyPath: KeyPath<Element, Value>)
    where Value: Equatable
{
    let itemValue = item[keyPath: keyPath]
    replaceOrAppend(item, whereFirstIndex: { [110][keyPath: keyPath] == itemValue })
}

Затем вы можете использовать его как:

[111 ]

И, конечно, если вы делаете это много, вы можете продолжать подниматься и подниматься.

protocol Identifiable {
    var id: Int { get }
}

extension Student: Identifiable {}

extension Array where Element: Identifiable {
    mutating func replaceOrAppendFirstMatchingID(_ item: Element)
    {
        replaceOrAppend(item, firstMatchingKeyPath: \.id)
    }
}

array.replaceOrAppendFirstMatchingID(alice0) // [alice1, alice0]
0
ответ дан Rob Napier 20 March 2019 в 15:13
поделиться

Предполагая, что ваши типы являются уравняемыми, это общее расширение:

extension RangeReplaceableCollection where Element: Equatable {

    mutating func addOrReplace(_ element: Element) {
        if let index = self.firstIndex(of: element) {
            self.replaceSubrange(index...index, with: [element])
        }
        else {
            self.append(element)
        }
    }
}

Однако имейте в виду, что моя (и ваша) функция заменит только один соответствующих элементов.

Испытание на полной рабочей площадке:

Playgrounds Test

0
ответ дан PeejWeej 20 March 2019 в 15:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: