1 (изменено: tuma4ok, 2016-02-10 01:50:03)

Тема: AHK: Сортировка массива

Здравствуйте, уважаемые форумчане. Недавно написал код для сортировки массива от меньшего значения к большему. Но мне кажется что мой код слишком большой и его можно в разы упростить. По этому обращаюсь к вам, к более опытным кодерам.
Вариант моей сортировки:


global ArrayLEADERS := Object()
global ArrayTopLeaders := Object()

ArrayLEADERS[x := "Qnton"] := 5
ArrayLEADERS[x := "Wnton"] := 6
ArrayLEADERS[x := "Enton"] := 12
ArrayLEADERS[x := "Rnton"] := 1
ArrayLEADERS[x := "Tnton"] := 22
ArrayLEADERS[x := "Ynton"] := 5
ArrayLEADERS[x := "Unton"] := 22

LastMaxPoint := 0
LastMaxName := ""
LastListArray := ""
CountPlayers := 0
CountListLeaders := 0

for name, point in ArrayLEADERS {
	if(point > LastMaxPoint) {
		LastMaxPoint := point
		LastMaxName := name
	}
}

LoopLastMaxPoint := LastMaxPoint + 1

Loop % LastMaxPoint {
	LoopLastMaxPoint -= 1
	for name, point in ArrayLEADERS {
		if(LoopLastMaxPoint = point) {
			LastListArray .= name "@"
		}
		CountPlayers := A_Index
	}
}

Loop, Parse, LastListArray, `@
	LastListDescArray := trim(A_LoopField "@" LastListDescArray, "@")

if(CountPlayers >= 5)
	CountListLeaders := 5
else
	CountListLeaders := CountPlayers

Loop, Parse, LastListDescArray, `@ 
{
	ArrayTopLeaders[ArrayLEADERS[y := A_LoopField], z := A_LoopField] := ArrayLEADERS[x := A_LoopField]
	if(CountListLeaders = A_Index)
		break
}

for key, val in ArrayTopLeaders {
	for name, point in val {
		msgbox % CountListLeaders " место занял " name ", он набрал " point " баллов."
		CountListLeaders -= 1
	}
}

Полное описание скрипта: Берет массив в ключе которого находится имя, а в значении кол-во очков (число). Дальше идет сортировка от меньшего значения к большему (это число хранится в значении ключа). Но, мне нужно вывести не более 5 значений.

Если есть варианты как-то упростить код (уменьшить его) напишите, пожалуйста. Очень поможете. Жду ваших ответов и вариантов.

2

Re: AHK: Сортировка массива

А почему по вашему коду первое место занимает ключ со значением 12, хотя большее — 22? Так и должно быть?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Сортировка массива

В общем, полная сортировка как-то так, а с какого конца пять отбирать, сами решите:

ArrayLEADERS := { Qnton: 5
					 , Wnton: 6
					 , Enton: 12
					 , Rnton: 1
					 , Tnton: 22
					 , Ynton: 5
					 , Unton: 22 }
					 
SortedArray := MySort(ArrayLEADERS)
for k, v in SortedArray
	MsgBox, % v[1] A_Tab v[2]
Return

MySort(obj)  {
	arr := []
	for k, v in obj
		arr.Push([k, v])
	Return Sorting(arr)
}

Sorting(arr)  {
	ArrMin := [], ArrMax := []
	for k, v in arr  {
		if (k = 1)
			continue
		array := arr[k, 2] < arr[1, 2] ? "ArrMin" : "ArrMax"
		%array%.Push(arr[k])
	}
	for k, v in ["ArrMin", "ArrMax"]
		(%v%.Length() > 1 && %v% := Sorting(%v%))
	
	Return ArrMin, ArrMin.Push(arr[1]), ArrMin.Push(ArrMax*)
}

Или, если элементов в массиве немного, такой вариант, более короткий, но и более затратный:

ArrayLEADERS := { Qnton: 5
					 , Wnton: 6
					 , Enton: 12
					 , Rnton: 1
					 , Tnton: 22
					 , Ynton: 5
					 , Unton: 22 }
					 
SortedArray := MySort(ArrayLEADERS)
for k, v in SortedArray
	MsgBox, % v[1] A_Tab v[2]
Return

MySort(_obj)  {
	arr := [], obj := _obj.Clone()
	for k, v in obj
		keys .= (A_Index = 1 ? "" : ",") . v
	Sort, keys, N D,
	Loop, parse, keys, `,
		for k, v in obj
			(A_LoopField = v && arr.Push([k, v]) && obj.Delete(k))
	Return arr
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

4

Re: AHK: Сортировка массива

teadrinker пишет:

А почему по вашему коду первое место занимает ключ со значением 12, хотя большее — 22? Так и должно быть?

Так не должно было быть, это наверное я не заметил, так как не тестировал на этих цифрах. И спасибо вам за ваши ответы, очень помогло.

5 (изменено: tuma4ok, 2016-02-10 15:46:36)

Re: AHK: Сортировка массива

Ещё возникло 2 вопроса, как узнать размер одномерного массива? Ну узнать сколько там элементов. В моем примере их 7.

Забыл про A_Index. Нашел решение.