Мне нужно поменять местами NSArray
.
Например:
[1,2,3,4,5]
должен стать: [5,4,3,2,1]
Каков наилучший способ достичь этого?
objective-c
nsarray
Энди Джейкобс
источник
источник
Ответы:
Чтобы получить обратную копию массива, посмотрите на решение danielpunkass, используя
reverseObjectEnumerator
.Для обращения изменяемого массива вы можете добавить в свой код следующую категорию:
источник
Существует гораздо более простое решение, если вы используете встроенный
reverseObjectEnumerator
методNSArray
иallObjects
методNSEnumerator
:allObjects
задокументировано как возвращение массива с объектами, которые еще не были пройденыnextObject
, в следующем порядке:источник
Некоторые тесты
1. reverseObjectEnumerator allObjects
Это самый быстрый метод:
Результат:
executionTime = 0.000026
2. Итерация по reverseObjectEnumerator
Это в 1,5–2,5 раза медленнее:
Результат:
executionTime = 0.000071
3. sortedArrayUsingComparator
Это в 30–40 раз медленнее (здесь никаких сюрпризов):
Результат:
executionTime = 0.001100
Так
[[anArray reverseObjectEnumerator] allObjects]
же, как и скорость, и легкость.источник
enumerateObjectsWithOptions:NSEnumerationReverse
?enumerateObjectsWithOptions:NSEnumerationReverse
- самый верхний завершился за0.000072
считанные секунды, блочный метод за0.000009
секундыУ DasBoot правильный подход, но в его коде есть несколько ошибок. Вот полностью обобщенный фрагмент кода, который перевернет любой NSMutableArray на месте:
Вы можете обернуть это в функцию C, или для бонусных баллов, используйте категории, чтобы добавить его в NSMutableArray. (В этом случае «массив» станет «я».) Вы также можете оптимизировать его, назначив
[array count]
переменную перед циклом и используя эту переменную, если хотите.Если у вас есть только обычный NSArray, нет способа отменить его на месте, потому что NSArrays нельзя изменить. Но вы можете сделать обратную копию:
Или используйте этот маленький трюк, чтобы сделать это в одной строке:
Если вы просто хотите перебрать массив в обратном направлении, вы можете использовать
for
/in
loop с[array reverseObjectEnumerator]
, но это, вероятно, немного более эффективно-enumerateObjectsWithOptions:usingBlock:
:( Примечание : существенно обновлено в 2014 году благодаря пятилетнему опыту работы с Foundation, новой функции Objective-C или нескольким советам из комментариев.)
источник
Изучив ответы других выше и найдя обсуждение Мэтта Галлахера здесь
Я предлагаю это:
Как заметил Мэтт:
Вскоре после этого он отвечает так:
источник
Категории Георга Шолли очень хорошие. Однако для NSMutableArray использование NSUIntegers для индексов приводит к падению, когда массив пуст. Правильный код:
источник
Самый эффективный способ перечислить массив в обратном порядке:
Использование
enumerateObjectsWithOptions:NSEnumerationReverse usingBlock
. Используя приведенный выше бенчмарк @ JohannesFahrenkrug, это в 8 раз быстрее, чем[[array reverseObjectEnumerator] allObjects];
:источник
источник
Обратный массив и цикл по нему:
источник
Чтобы обновить это, в Swift это можно легко сделать с помощью:
источник
Что касается меня, вы рассматривали, как массив был заполнен в первую очередь? Я находился в процессе добавления МНОГИХ объектов в массив и решил вначале вставить каждый из них, увеличивая все существующие объекты на один. В этом случае требуется изменяемый массив.
источник
Или Скала-путь:
источник
Есть простой способ сделать это.
Надеюсь, это поможет.
источник
Я не знаю ни одного встроенного метода. Но ручное кодирование не так уж сложно. Предполагая, что элементы массива, с которым вы имеете дело, являются объектами NSNumber целочисленного типа, а 'arr' - это NSMutableArray, который вы хотите сторнировать.
Так как вы начинаете с NSArray, вам нужно сначала создать изменяемый массив с содержимым исходного NSArray ('origArray').
Редактировать: Исправлено n -> n / 2 в счетчике циклов и изменено NSNumber на более общий идентификатор из-за предложений в ответе Брента.
источник
Если все, что вы хотите сделать, это повторить в обратном порядке, попробуйте это:
Вы можете сделать [myArrayCount] один раз и сохранить его в локальной переменной (я думаю, это дорого), но я также предполагаю, что компилятор будет делать то же самое с кодом, как написано выше.
источник
Синтаксис Swift 3:
источник
Попробуй это:
источник
Вот хороший макрос , который будет работать на любом NSMutableArray ИЛИ NSArray:
Чтобы использовать просто позвоните:
reverseArray(myArray);
источник