Онлайн-справочник по самым часто задаваемым вопросам из темы "Как сделать?" на форуме QSP.su

20.10. Как отсортировать данные?

В: Как отсортировать данные? Например, список персонажей по алфавиту, или набор чисел от меньшего к большему.

О:

Прежде всего такие данные должны лежать в одном массиве. Например:

$personage[0]='Петя'
$personage[1]='Ваня'
$personage[2]='Сева'
$personage[3]='Саша'
$personage[4]='Лёня'

Или:

number[0]=345
number[1]=798
number[2]=930
number[3]=121
number[4]=474

Далее можно воспользоваться простым алгоритмом:

! объявляем локальные переменные
local $varMax, index, $personage_temp
! копируем данные во временный массив,
! чтоб не затереть исходный
copyarr '$personage_temp','$personage'
! с помощью цикла выбираем элементы по одному
! из временного массива, имеющие минимальное значение
loop while arrsize('$personage_temp')>0:
! цикл будет работать, пока размер временного массива
! больше нуля
    
! получаем минимальное значение
    $varMax=$min('$personage_temp')
    
! определяем, в каком элементе лежит это значение
    index=arrpos('$personage_temp',$varMax)
    
! выводим на экран
    *pl $varMax
    
! или запоминаем в другом массиве
    $personage_sort[]=$varMax
    
! удаляем элемент из временного массива
    killvar '$personage_temp',index
end

Обратите внимание, при работе с текстовыми значениями меньшим считается то, которое идёт раньше согласно алфавитного порядка.

Сортировка чисел ничем практически не отличается:

local varMax, index, number_temp
copyarr 'number_temp','number'
loop while arrsize('number_temp')>0:
    varMax=max('number_temp')
    index=arrpos('number_temp',varMax)
    *pl varMax
    number_sort[]=varMax
    killvar 'number_temp',index
end

Этот алгоритм достаточно быстр и прост для решения большинства задач. Он требует нескольких переменных и дополнительный массив для временного хранения данных. Если необходимо отсортировать данные сразу внутри массива, не прибегая к помощи дополнительного массива, можно воспользоваться методом сортировки "пузырьком":

проходы=0
loop local проходы=0 while проходы<arrsize("сортируемый_массив") step проходы+=1:
    loop local всплытия=проходы while всплытия<arrsize("сортируемый_массив") step всплытия+=1:
        if сортируемый_массив[проходы] < сортируемый_массив[всплытия]: 
            
! или, если нужен другой порядок: 
            
!if сортируемый_массив[проходы] > сортируемый_массив[всплытия]: 
            запоминальная_переменная = сортируемый_массив[проходы] 
            сортируемый_массив[проходы] = сортируемый_массив[всплытия] 
            сортируемый_массив[всплытия] = запоминальная_переменная 
        end
    end
end

Операции сравнения прекрасно работают с текстовыми значениями по тому же принципу, что и функции `$max` и `$min`.

Готовое решение по методу сортировки пузырьком есть в библиотеке "easy.math" с различными дополнительными возможностями. Смотрите функцию em.arr.sort.