Сортировка AS3 по вектору не работает должным образом - PullRequest
1 голос
/ 05 июля 2011

У меня есть вектор фиксированной длины 9 с некоторыми объектами. каждый объект имеет переменную value: Point и вектор должны быть отсортированы таким образом, чтобы объекты с более высоким значением value.x появлялись первыми, а если их значение value.x совпадает, то объект с меньшим значением value.y должен быть первым.

это моя функция сравнения:

    private function cmpr(h1:HelpObj, h2:HelpObj):Number{ 
        var res:Number;
        if(h1.value.x==h2.value.x){
            res = h1.value.y-h2.value.y;
            return res;
        }
        else{
            res = h2.value.x-h1.value.x;
            return res;
        }
    }

но, как вы можете видеть на этом скриншоте, результирующий порядок не соответствует предполагаемому:

problem

что я делаю не так?

Ответы [ 2 ]

6 голосов
/ 05 июля 2011

Функция сравнения получает аргументы a и b.

Он должен вернуть

  • -1, если a должен быть размещен до b
  • 0, если позиции b и a равны
  • 1, если a необходимо поставить после b

Вы возвращаете любые значения, а не только три перечисленных, поэтому порядок испорчен.

Сравните результаты в примере ниже.

var test:Vector.<Number>;

// returning whatever the difference is
var sortMethod1:Function = function (a:Number, b:Number) : Number
{
    var value:Number = a-b;
    trace(a+"\t"+b +"\t= "+ value);
    return value;
}

// returning -1, 0, 1
var sortMethod2:Function = function (a:Number, b:Number) : int
{
    var result:int;
    if (a < b) {
        result = -1;
    } else if (a > b) {
        result =  1;    
    } else {
        result 0;
    }
    trace(a+"\t"+b +"\t: "+ result);
    return result;
}

test = new <Number>[1.2,1.1,1.4,1.5,0];
trace("BEFORE", test);
test.sort(sortMethod1);
trace("AFTER1", test);

trace("--");

test = new <Number>[1.2,1.1,1.4,1.5,0];
trace("BEFORE", test);
test.sort(sortMethod2);
trace("AFTER2", test);

/*
Trace output:

BEFORE 1.2,1.1,1.4,1.5,0
1.1 1.4 = -0.2999999999999998
1.2 1.4 = -0.19999999999999996
1.5 1.4 = 0.10000000000000009
0   1.4 = -1.4
0   1.4 = -1.4
1.1 1.2 = -0.09999999999999987
0   1.2 = -1.2
1.5 1.2 = 0.30000000000000004
1.5 1.2 = 0.30000000000000004
0   1.2 = -1.2
0   1.1 = -1.1
AFTER1 0,1.1,1.2,1.5,1.4
--
BEFORE 1.2,1.1,1.4,1.5,0
1.1 1.4 : -1
1.2 1.4 : -1
1.5 1.4 : 1
0   1.4 : -1
1.5 1.4 : 1
0   1.4 : -1
0   1.1 : -1
1.1 1.2 : -1
AFTER2 0,1.1,1.2,1.4,1.5
*/

РЕДАКТИРОВАТЬ В вашем случае это будет следующим:

private function cmpr(h1:HelpObj, h2:HelpObj):int
{ 
    var hx1:Number = h1.value.x;
    var hx2:Number = h2.value.x;
    if (hx1 < hx2) {       
        return -1;
    }
    if (hx1 > hx2) {       
        return 1;
    }
    var hy1:Number = h1.value.y;
    var hy2:Number = h2.value.y;
    if (hy1 < hy2) {       
        return -1;
    }
    if (hy1 > hy2) {       
        return 1;
    }
    return 0;
}
5 голосов
/ 13 ноября 2012

Есть такая же проблема. Функция Vector.sort () содержит ошибку. Если вы работаете с числами с плавающей точкой, вы не должны возвращать маленькие числа, такие как -0,0034 так что ...

someSortFunc( a:SomeObject , b:SomeObject ):Number
{
  return a.val - b.val; //unexpected results
}

someSortFunc( a:SomeObject , b:SomeObject ):Number
{
  return 1000 * ( a.val - b.val ); //correct results
}

так что лучше используйте -1, 1 или 0 :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...