#ios #swift #xcode
#iOS #swift #xcode
Вопрос:
У меня есть список массивов, которые выглядят следующим образом:
var lists = [[Category]]()
Каждый элемент в «списках» представляет собой массив объектов (категория), я пытаюсь повторно ввести «списки» (очистить каждый элемент) после его использования.
Мой подход:
lists.forEach { list in
list.removeAll()
}
Ошибка: не удается изменить «список», потому что «список» является постоянной переменной
Могу ли я в любом случае достичь своей цели в Swift?
Комментарии:
1. Почему бы просто не сделать
lists = [[Category]]()
? (снова возвращается к значению по умолчанию)2. Извините, что не прояснил мою проблему, моя цель — очистить весь массив, который хранится в «списках», а не повторно вводить «списки». У меня есть вызов функции clearList([[Категория]]), я хочу удалить все элементы массива, которые я передаю в функцию. Выглядит так: clearList([listCate1, listCate2, …]) если я хочу удалить больше списка, мне просто нужно пройти через параметр массива.
Ответ №1:
Поскольку массивы являются типами значений и имеют семантику копирования при записи, «очистка всех вложенных массивов массива» неотличима от «создания нового массива с таким количеством пустых вложенных массивов, сколько вложенных массивов в старом массиве, и переназначение его старому массиву».
Итак, вы можете сделать
lists = Array(repeating: [], count: lists.count)
В качестве альтернативы:
lists = lists.map { _ in [] }
Из комментариев кажется, что вы пишете функцию, которая очищает все вложенные массивы. В этом случае вам нужен inout
параметр:
func clearList(_ lists: inout [[Category]]) {
lists = Array(repeating: [], count: lists.count)
}
И вызвать его:
var myLists = [listCate1, listCate2]
clearList(amp;myLists)
// myLists will be [[], []], note that this does not change listCate1 or listCate2
Если вы действительно хотите, чтобы ваша функция изменяла произвольное количество передаваемых вами списков, вам нужно будет использовать небезопасные указатели (очень не рекомендуется):
func clearList(_ lists: UnsafeMutablePointer<[Category]>...) {
for list in lists {
list.pointee = []
}
}
И clearList(amp;listCate1, amp;listCate2)
на самом деле изменил listCate1
бы и listCate2
, но это довольно грязный трюк.
Комментарии:
1. Я думаю, что это моя ошибка, когда я не проясняю свою проблему, у меня есть функция под названием «clearList», цель которой — очистить каждый список, который я передаю, поэтому «списки», о которых я упоминал выше, — это просто контейнер. Здесь я хочу удалить все элементы списка, которые я передаю в функции, поэтому я использую «списки» для хранения всех этих списков. Это выглядит примерно так: clearList([listCate1, listCate2, …]) если я хочу удалить больше списка, мне просто нужно передать через параметр array.
2. @BacSon я попытался добиться того, чего вы хотите. См. Редактирование. Похоже, вы неправильно понимаете тип значения Swift. Всякий раз, когда вы присваиваете их чему-либо, передаете их в функцию или когда вы что-то в них меняете, вы создаете копию значения.
3. Большое вам спасибо за помощь, это моя ошибка, когда я не уточняю, в чем моя проблема. На самом деле я хочу изменить listCate1 и listCate2, удалить все их элементы, но если это грязный трюк, я бы предпочел не использовать. Просто измените его на обычный способ clearList() { listCate1.removeAll(), listCate2.removeAll() } Мне просто интересно, есть ли более разумное решение для этой проблемы
Ответ №2:
Вы можете назначить пустой литерал массива, который записывается как [ ] (пустая пара квадратных скобок)
lists = []
списки теперь представляют собой пустой массив, но все еще типа [[Category]]
Ответ №3:
Вы можете удалить все элементы массива и сохранить емкость.
lists.removeAll(keepingCapacity: true)
или, если вы хотите удалить объект из массива на основе некоторых условий, вы можете использовать это…
lists.removeAll { (obj) -> Bool in
if <check some condition { return true }
else { false }
}
Ответ №4:
Я бы создал расширение с изменяемыми и неизменяемыми вариантами. Расширяя RangeReplaceableCollection
, а не Array
ограничивая, нам не нужно ограничивать Array.Element
какой-либо конкретный тип.
extension RangeReplaceableCollection where Element: RangeReplaceableCollection {
func stripped() -> Self {
return .init(repeating: .init(), count: count)
}
mutating func strip() {
self = stripped()
}
}
Теперь мы можем удалить их на месте, если наш массив объявлен изменяемым:
var mutable: [[Category]] = []
mutable.strip()
Или мы можем использовать неизменяемый вариант для let
констант:
let immutable: [[Category]] = []
let stripped = immutable.stripped()
Ответ №5:
var someInts1 = [30,11,34]
var someInts2 = [30,11,34]
var someInts3 = [30,11,34]
var lists = [Any]()
lists = [someInts1, someInts2, someInts3]
print(lists) // [[30,11,34], [30,11,34], [30,11,34]]
lists = [] // this is where the list become empty
print(lists) // []