Есть ли в Swift возможность работать с обратными диапазонами?
Например:
for i in 5...1 {
// do something
}
это бесконечный цикл.
В более новых версиях Swift этот код компилируется, но во время выполнения выдает ошибку:
Неустранимая ошибка: не удается сформировать диапазон с верхним пределом <нижний предел
Я знаю, что могу использовать 1..5
вместо этого, вычислять j = 6 - i
и использовать в j
качестве индекса. Мне просто интересно, есть ли что-нибудь более разборчивое?
Ответы:
Обновление для последней версии Swift 3 (все еще работает в Swift 4)
Вы можете использовать
reversed()
метод в диапазонеИли
stride(from:through:by:)
методstide(from:to:by:)
аналогично, но исключает последнее значениеОбновление для последней версии Swift 2
Прежде всего, расширения протокола меняют способ
reverse
использования:for i in (1...5).reverse() { print(i) } // 5 4 3 2 1
Страйд был переработан в Xcode 7 Beta 6. Новое использование:
Он также работает для
Doubles
:Остерегайтесь сравнений с плавающей запятой здесь для определения границ.
Предыдущее изменение для Swift 1.2 : Начиная с Xcode 6 Beta 4, by и ReverseRange больше не существуют: [
Если вы просто хотите изменить диапазон, обратная функция - это все, что вам нужно:
Как указано в сообщении 0x7fffffff, есть новая конструкция шага, которую можно использовать для итерации и увеличения на произвольные целые числа. Apple также заявила, что скоро появится поддержка с плавающей запятой.
Источник из его ответа:
источник
(1...5).reverse()
(как вызов функции), обновите свой ответ. (Так как это всего два символа, я не мог редактировать ваш пост.)(1...5).reversed()
. Кроме того, пример для.stride()
не работает, иstride(from:to:by:)
вместо него требуется бесплатная функция .stride
код для swift 3 немного неверен. чтобы включить число 1, вам нужно будет использоватьthrough
вместоto
этого:for i in stride(from:5,through:1,by:-1) { print(i) }
reversed
него сложность O (1), потому что он просто обертывает исходную коллекцию и не требует итерации для ее создания.В асимметрии этого есть что-то тревожное:
... в отличие от этого:
Это означает, что каждый раз, когда я хочу сделать обратный диапазон, я должен не забыть поставить круглые скобки, плюс я должен написать это
.reverse()
в конце, торча, как больной палец. Это действительно некрасиво по сравнению с C-стилем для циклов, которые симметричны, считая вверх и вниз. Поэтому я предпочел использовать C-стиль для циклов. Но в Swift 2.2 цикл for в стиле C уходит! Поэтому мне пришлось поспешно заменить все мои декрементирующие циклы for в C-стиле этой уродливой.reverse()
конструкцией - все время задаваясь вопросом, почему, черт возьми, нет оператора обратного диапазона?Но ждать! Это Swift - нам разрешено определять собственные операторы !! Вот так:
Итак, теперь я могу сказать:
Это охватывает только наиболее распространенный случай , что происходит в моем коде, но это , несомненно, самый распространенный случай, так что это все нужно , я в настоящее время .
У меня был какой-то внутренний кризис с оператором. Я бы хотел использовать
>..
, как обратное..<
, но это незаконно: похоже, вы не можете использовать точку после точки, не являющейся точкой. Я подумал,..>
но решил, что это слишком сложно отличить..<
. Приятно то,>>>
что он кричит на вас: « вниз !» (Конечно, вы можете придумать другого оператора. Но мой совет: для суперсимметрии определите<<<
, что делать..<
, и теперь у вас есть<<<
и>>>
. , Которые симметричны и легко печатать)Версия Swift 3 (Xcode 8 seed 6):
Версия Swift 4 (Xcode 9 beta 3):
Версия Swift 4.2 (Xcode 10 beta 1):
Версия Swift 5 (Xcode 10.2.1):
источник
>>>
оператор действительно классный! Я надеюсь, что дизайнеры Swift обратят внимание на подобные вещи, потому что придерживатьсяreverse()
конца выражений в скобках кажется странным. Нет никаких причин, по которым они не могли обрабатывать5>..0
диапазоны автоматически, потому чтоForwardIndexType
протокол предоставляет вполне разумныйdistanceTo()
оператор, который можно использовать для определения того, должен ли шаг быть положительным или отрицательным.Похоже, что ответы на этот вопрос немного изменились по мере прохождения бета-тестирования. Начиная с бета-версии 4, и
by()
функция, иReversedRange
тип были удалены из языка. Если вы хотите сделать обратный диапазон, теперь у вас есть следующие варианты:1: Создайте прямой диапазон, а затем используйте
reverse()
функцию, чтобы перевернуть его.2: Используйте новые
stride()
функции, которые были добавлены в бета-версии 4, которая включает функции для указания начального и конечного индексов, а также количества для итерации.Обратите внимание, что я также включил в этот пост новый оператор исключительного диапазона.
..
был заменен на..<
.Изменить: из примечаний к выпуску Xcode 6 beta 5 Apple добавила следующее предложение для решения этой проблемы:
Вот вам пример.
источник
lazy(0....5).reverse()
и не вижу примечания к выпуску бета 5. Знаете ли вы о других обсуждениях по этой теме? Кроме того, к вашему сведению, числа внутри этогоfor
цикла в вашем примере указаны наоборот.// 0, 1, 2, 3, 4, 5
но на самом деле его нужно поменять местами. Комментарий вводит в заблуждение.Xcode 7, бета 2:
источник
Swift 3, 4+ : это можно сделать так:
результат : 10, 9, 8 ... 0
Вы можете настроить его как хотите. Для получения дополнительной информации прочтите
func sequence<T>
ссылкуисточник
Это может быть другой способ сделать это.
источник
Функция Reverse () используется для обратного числа.
Var n: Int // Введите число
Для i в 1 ... n.reverse () {Print (i)}
источник