2011-02-08 6 views
0

У меня есть 2D-массив, называемый «результаты». Каждый массив «row» в результатах содержит как строковые, так и целочисленные значения. Я использую этот скрипт для сортировки массива по любому колонку «» на событии OnClick:Сортировка многомерного массива с помощью Javascript: целые числа

function sort_array(results, column, direction) { 
var sorted_results = results.sort(value); 
function value(a,b) { 
    a = a[column]; 
    b = b[column]; 
    return a == b ? 0 : (a < b ? -1*direction : 1*direction) 
    } 
} 

Это прекрасно работает для столбцов со строками. Но он обрабатывает столбцы целых чисел, таких как строки вместо цифр. Например, значения 15, 1000, 200, 97 будут отсортированы 1000, 15, 200, 97, если «восходящий» или 97, 200, 15, 1000 «нисходящий».

Я проверил typeof целые значения, и скрипт знает, что они числа. Как я могу заставить его рассматривать их как таковые?

ответ

1

Сделайте типы a и b частью сравнения, которая решает, что возвращает функция value. В этом процессе вам придется решить, как сортировать целые числа по отношению к строкам.

В качестве альтернативы вы можете иметь функцию сравнения, которая принимает значения, и выполняет замену, чтобы заменить каждую строку цифр строкой цифр фиксированной длины, с ведущими нулями, а затем строковыми сравнениями. Преимущество такого подхода заключается в том, что вы завершаете сортировку таких вещей, как «a2», «a9», «a10» и т. Д. Что обычно нравится людям.

0

Вы уверены, что они цифры? Как вы проверили? Попробуйте эту модификацию, чтобы заставить их быть числами только в случае, если:

if (isNumberColumn(column)) { 
    a = +a; 
    b = +b; 
} 
0

Я думаю, что вы будете иметь, чтобы сделать предварительный проход по значениям в столбце перед сортировкой. Зачем? Ну, вы должны знать заранее (до сортировки, то есть), могут ли все значения рассматриваться как числа. Если они могут, то функция «значение» может их преобразовать. В противном случае он должен сортировать их как строки.

0

вы можете попытаться сделать свою собственную функцию сравнения, соответствующую вашим потребностям. Вы можете определить свой собственный способ сравнения строк с ints. ex:

function getDirection(a,b){ 
    if(typeof(a) == typeof(b)) 
     return a == b ? 0 : (a>b?1:-1); 
    a+="";b+=""; 
    if(a[0] == '-') 
     { 
      if(b[0] != '-') 
       return 1; 
     } 
    else 
     if(b[0] != '-') 
      return -1; 
    return a[0] == b[0] ? 0 : (a[0]>b[0]?1:-1); 
} 

Надеюсь, это поможет.

0

Во-первых: сортировка является мутатором, что означает, что сортировка происходит на месте. Таким образом, чтобы избежать непреднамеренных consequeces, я бы изменить

var sorted_results = results.sort(value); 

в

var sorted_results = results.slice(0).sort(value); 

если, конечно, вы хотите это сортируется на месте, но что же вам нужно sorted_results переменную?

Что касается самой сортировки, то целочисленная сортировка, по-видимому, отлично подходит для меня, проблема в том, что это действительно строки в смешанном целочисленном и строчном сценариях, как показано в его примере: http://jsfiddle.net/QJ5fM/, где он сортирует следующие массивы довольно разному:

[[16],[131],['aa'],['0hey'],[176],[100],['hey'],[1],[12]]; 
[['aa'],[16],[131],['0hey'],[176],[100],['hey'],[1],[12]]; 
[['aa'],['0hey'],[16],[131],[176],[100],['hey'],[1],[12]]; 

дает следующий результат в хроме 9:

1,12,0hey,aa,hey,16,100,131,176 
1,12,0hey,16,100,131,176,aa,hey 
1,12,16,100,131,176,0hey,aa,hey 

следующее в Firefox 3.6:

1,12,0hey,aa,hey,16,100,131,176 
1,12,0hey,hey,16,100,131,176,aa 
1,12,hey,16,100,131,176,0hey,aa 

и следующее в ie8:

0hey,aa,hey,1,12,16,100,131,176 
0hey,aa,hey,1,12,16,100,131,176 
0hey,aa,hey,1,12,16,100,131,176 

Как сюрприз здесь, кажется, ie8 имеет единственный разумный, или, по крайней мере, последовательны, реализация: P

Смежные вопросы