Может кто-нибудь сказать мне, почему этот код JavaScript не выстраивает в порядок массив? - PullRequest
1 голос
/ 29 декабря 2010

Живой код: http://jsfiddle.net/fCUZC/

//INPUT ARRAY:
var input = [28,32,21,11,8,2,14,32,64];
//VARIABLE DECLARATION. a = highest number so far, b = position of that number
entireLoop:
for (var i = 1; i<=input.length; i++)
{
    if(input[i] > input[i-1])
    {
        for(var o = i; o>=0; o--)
        {
            if(input[i-1] > input[o])
            {
                input.splice(i,0,input[o]);
                input.splice((o+1),1);
                continue entireLoop;
            }
            else if(input[o] > input[0])
            {
                input.splice(0,0,input[o]);
                input.splice((o+1),1);
                continue entireLoop;
            }

        }
    }
}
document.write(input);

Я пытаюсь упорядочить массив от наибольшего к наименьшему, но где-то застряло 32.Я знаю, что есть метод сортировки, но я новичок и хочу попробовать это для себя.

Ответы [ 2 ]

5 голосов
/ 29 декабря 2010

** edit ** Сначала взглянем на собственный метод массива .sort ().Он оставляет исходный массив без изменений и принимает функцию сравнения.Последнее делает .sort () довольно мощным.

var input = [28,32,21,11,8,2,14,32,64];

var low2high = function ( a , b ) {
    return a > b;
};

var high2low = function ( a , b ) {
    return a < b;
};

var resultHigh2low = input.sort( high2low ); // [ 64,32,32,28,21,14,11,8,2 ];
var resultLow2high = input.sort( low2high ); // [ 2,8,11,14,21,28,32,32,64 ];

Так что, если мы хотим использовать bubbleSort (ссылка предоставлена ​​TJ Crowder, см. Комментарии OP), мы можем написать следующее:

// javascript bubbleSort implementation
var bubbleSort = function ( list , comparison ) {
    var swapped;
    var i;
    var val;

    list = [].concat( list ); // do not destroy original
    comparison = ( typeof comparison == "function" ) ? comparison : function(a,b){return a > b;}

    do {
        i = list.length;
        while ( --i ) {
           if ( i && comparison( list[ i ] , comparison[ i-1] ) ) {
                val = list[ i ];
                list[ i ] = list[ i - 1 ];
                list[ i - 1] = val;
                swapped = true;
           }
        }
    } while ( swapped );
    return list;
}

// using comparison functions from previous example.
var resultHigh2low = bubbleSort( input , high2low ); // [ 64,32,32,28,21,14,11,8,2 ];
var resultLow2high = bubbleSort( input , low2high ); // [ 2,8,11,14,21,28,32,32,64 ];

Давайте пройдемся по ней шаг за шагом:

var bubbleSort = function ( list , comparison ) {
    ..code..
}

Наша функция принимает 2 параметра, первый - массив, а второй - опциональную функцию сравнения.

var swapped;
var i = list.length;
var val;

Мы сохраняем длину списка впеременную i и объявим 2 пустые переменные (swapped и val), которые мы будем использовать позже.

list = [].concat( list ); // do not destroy original

Мы клонируем список, используя [].concat( array ), и перезаписываем локальную *Переменная 1020 * оставляет исходную нетронутой.

comparison = ( typeof comparison == "function" ) ? comparison : function(a,b){return a > b;}

Мы проверяем аргумент typeof comparison, если это function, мы используем этот аргумент, в противном случае мы откатимся сами по себе comparisonфункция.Наша резервная функция сравнения вернет true, если a больше b.

do {
    ..code..
} while ( swapped );

Цикл do / while будет запущен хотя бы один раз, наша переменная swapped в настоящее время undefinedтак что это будет истолковано как ложное.Если наша функция comparison возвращает значение true, происходит перестановка, и переменная swapped будет установлена ​​в значение true, поэтому она будет повторяться снова.

while ( --i ) {
    ..code..
}

Здесь я выполняю цикл от длины списка вниз, *Оператор 1041 * ставится перед переменной i, чтобы гарантировать, что она обрабатывается первой перед чем-либо, i-- сработает после оценки while, что приведет к ошибочным результатам, поскольку list[ list.length ] не существует.Я всегда так делаю (возможно, плохой хаббит), но если это вас смущает, переходите к абсолютной прозрачности.

if ( i && comparison( list[ i ] , comparison[ i-1] ) ) {
    ..code..
}

Сначала мы проверяем, имеет ли i истинное значение (0 оценивается как ложное) изатем мы запускаем функцию comparison, передавая list[ i ] и list[ i - 1 ] как параметры a и b.Если функция comparison возвращает true, мы выполняем своп.

val = list[ i ];
list[ i ] = list[ i - 1 ];
list[ i - 1] = val;
swapped = true;

Здесь я выполняю своп без использования метода .splice(), это просто образованное предположение, но я считаю, чтоназначения выполняются быстрее, чем вызовы функций.Я использую переменную val в качестве заполнителя.После того, как своп завершен, я установил для swapped значение true, поэтому наш цикл do / while будет продолжен.

return list;

Хорошо ... вернем результат.

Я исключил некоторыепроверяет, например, что мы делаем, когда длина списка равна нулю и еще много чего.По сути, при написании вспомогательных функций нам также необходимо иметь дело с обработкой ошибок.Как, например, выдача TypeError, когда переданный аргумент сравнения не является функцией, гарантируя, что метод сравнения возвращает логическое значение и т. Д.

2 голосов
/ 29 декабря 2010
//INPUT ARRAY:
var input = [28,32,21,11,8,2,14,32,64];
//VARIABLE DECLARATION. a = highest number so far, b = position of that number
for (var i = 1; i<input.length; i++)
{
    if(input[i] > input[i-1])
    {
        for(var o = i-1; o>=0; o--)
        {
            if(input[i] > input[o])
            {
                input.splice(i+1,0,input[o]);
                input.splice((o),1);
                i--;
            }       
        }
    }
}
document.write(input);

Хотя это все еще не здорово, оно должно работать. Имейте в виду, я только что проверил это, и я довольно неопытен с javascript. Ваши намерения были не так уж плохи, и всем нужно с чего-то начинать.

Самая большая проблема была просто внутренняя обусловленность. Я вижу вашу логику зацикливания назад от большого значения, которое вы нашли, и сдвигания всех меньших значений вправо. К сожалению, ваши показатели немного не в порядке. Вам также нужно запускать этот цикл до тех пор, пока он не завершится нормально, а не продолжить, иначе вы переключите только одно значение. Когда это условие исправлено, второе больше не нужно

Альтернативной формой было бы начать с самого низкого индекса и найти первое значение, которое меньше input [i], и поместить его туда. Это потенциально более понятно.

Я думаю, что это был неплохой первый выстрел, и было не так уж сложно начать работать. Удачи!

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