Безопасно ли удалять значения из словаря во время итерации в swift?

#swift #xcode

#swift #xcode

Вопрос:

Итак, мой код не разбился, но кажется, что это не должно быть безопасно, но я не могу найти четкого ответа в документах swift. Я перебираю словарь с for-in помощью цикла и удаляю эти элементы, если они не найдены в ссылочном массиве. Мне интересно, безопасно ли это, и если да, то почему?

     func cleanupETADictionary(trips: [Int64]){
        for (tripId, _) in etaDictionary{
            if !trips.contains(tripId){
                etaDictionary.removeValue(forKey: tripId)
            }
        }
    }
 

Комментарии:

1. Должно быть хорошо… почему это должно быть небезопасно?

2. С точки зрения словаря это должно быть безопасно, потому что ‘removeValue’ вернет nil, если ключ не найден. Это может снизить производительность, если у вас очень длинный массив / словарь.

Ответ №1:

Итерация работает не так, как вы думаете. Ваша итерация etaDictionary является копией оригинала. Словари — это типы значений в Swift.

Наглядный пример:

 var dictionary = [1: 1, 2: 2, 3: 3, 4: 4, 5: 5]

for kvp in dictionary {
  dictionary = [:]
  print(kvp)
  print(dictionary.count)
}
 

выводит:

 (key: 5, value: 5)
0
(key: 3, value: 3)
0
(key: 4, value: 4)
0
(key: 1, value: 1)
0
(key: 2, value: 2)
0
 

Однако для вашего цикла for есть имя; он вызывается filter . Используйте его вместо этого.

 func cleanupETADictionary(trips: [Int64]){
  etaDictionary = etaDictionary.filter { trips.contains($0.key) }
}
 

Комментарии:

1. Теперь, что, если вы напечатаете dictionary.count после завершения цикла for в вашем примере?

2. Также я не знаю, будет ли работать фильтр. Массив trips — это массив trips, который я хочу сохранить. Итак, в основном я хочу указать словарю из n элементов сохранить этот набор элементов и избавиться от остальных.