Связывание фильтра и массива карт по словарным значениям в Swift - PullRequest
2 голосов
/ 21 июня 2020

как я могу использовать этот тип цепочки

let numbers = [20,17,35,4,12]
let evenSquares = numbers.filter{$0 % 2 == 0}.map{$0 * $0}

в таком случае использования

У меня есть массив объектов, я хочу отфильтровать его по клавишам внешнего словаря, а затем назначить им значение отфильтрованных объектов словаря, где идентификатор объекта = ключ словаря, а затем отсортировать объект результата по значению словаря

вот код, который у меня есть сейчас:

let scoreDict: [String: Double]
var objects: [Object]
var filteredObjects = objects.filter { scoreDict.keys.contains.contains($0.id.uuidString.lowercased()) }
// .. and what next?
var scoresAssigned = filteredObjects.map { $0.score = scoreDict[$0.id.uuidString.lowercased()] } // This do not compile ""Cannot assign to property: '$0' is immutable"

1 Ответ

0 голосов
/ 21 июня 2020

Предполагая, что Object - это struct, на основании сообщения об ошибке ...

Это просто показывает, что функции высшего порядка не должны использоваться везде . map преобразует каждый элемент в последовательности во что-то еще. Поэтому вместо назначения score вам нужно вернуть новый Object с измененным score.

var scoresAssigned = filteredObjects.map { $0.withScore(scoreDict[$0.id.uuidString.lowercased()]) }

withScore будет выглядеть примерно так:

func withScore(_ score: Int) -> Object {
    var copy = self
    copy.score = score
    return copy
}

Но , если вы просто хотите присвоить счету новое значение, я рекомендую простое для l oop.

for i in 0..<filteredObjects.count {
    filteredObjects[i].score = scoreDict[$0.id.uuidString.lowercased()]
}

Также обратите внимание, что вам нужно получить доступ к словарю только один раз. Если ноль, ключ не существует.

var filteredObjects = [Object]()
for i in 0..<objects.count {
    if let score = scoreDict[$0.id.uuidString.lowercased()] {
        objects[i].score = score
        filteredObjects.append(objects[i])
    }
}
...