Обработка нулей в функции сортировки

Я не знаю, как обрабатывать nils мою функцию сортировки.

Когда у меня есть эта проверка, table.sort падает после некоторых вызовов.

if a == nil then
    return false
elseif b == nil then
    return true
end

С этой ошибкой: недопустимая функция порядка для сортировки. Но согласно документации функция сортировки должна возвращать false, если a следует за b. Правда иначе.

Если я удалю удалить этот код, он, конечно, выйдет из строя из-за нулевых индексов.


person mnn    schedule 20.01.2010    source источник
comment
Вы должны опубликовать больше кода. Получение нулей в вашей функции сравнения подозрительно. Вы уверены, что проблема там, а не где-то рядом?   -  person sbk    schedule 21.01.2010


Ответы (2)


Это практически не связано со значениями nil в таблице. Сообщение об ошибке генерируется, если сама функция сравнения недействительна. Из документации для table.sort:

Если задано comp, то это должна быть функция, которая получает два элемента таблицы и возвращает истину, когда первый меньше второго (так что not comp(a[i+1],a[i]) будет истинным после сортировки).

Другими словами, comp(a,b) должно подразумевать not comp(b,a). Если это отношение не выполняется, то, скорее всего, возникнет ошибка «недопустимая функция порядка для сортировки». (Обратите внимание, что он может быть поднят не во всех случаях.)

Чтобы быть более полезными, нам действительно нужно видеть всю функцию, переданную table.sort.

person RBerteig    schedule 21.01.2010
comment
+1: после тестирования кода из вопроса он правильно обрабатывает нулевые значения в массиве. Проблема должна заключаться в несоответствии остальной части функции. - person gwell; 26.01.2010
comment
Следует подчеркнуть, что comp(a,b) -> !comp(b,a) выполняется, а comp(a,b) == !comp(b,a) — нет; как и в случае a==b, где функция вернет false для обоих вызовов comp(). - person RJFalconer; 20.07.2011

Чтобы поместить все нулевые значения в начало массива:

  function mycomp(a,b)
    if a == nil and b == nil then
      return false
    end
    if a == nil then
      return true
    end
    if b == nil then
      return false
    end
    return a < b
  end

Чтобы поместить все нулевые значения в конец массива:

function mycomp(a,b)
  if a == nil and b == nil then
    return false
  end
  if a == nil then
    return false
  end
  if b == nil then
    return true
  end
  return a < b
end
person Long Cheng    schedule 20.01.2010
comment
Извините, наверное, я недостаточно хорошо объяснил: во-первых, в таблице НЕТ НУЛЯ. Во-вторых, table.sort явно не хочет иметь так много условий, потому что, когда я удаляю проверку nil, она продолжается, но падает на nil. - person mnn; 20.01.2010