Итак, у меня есть некоторые данные для руководства по скалолазанию, которое я пишу. На последней странице я хочу перечислить все маршруты, отсортированные по уровню сложности. Дело в том, что обычная сортировка здесь не применима.
Краткое объяснение уровней скалолазания (система YDS):
Уровень — это одномерная величина, указывающая сложность скалолазания. Уровни обозначаются числами, а начиная с уровня 10 и далее подразделяются на четыре уровня, обозначаемые буквами a, b, c и d.
Примеры: 8, 9, 10а, 10в, 11б
Иногда оценки делятся на две, а не на четыре, что обозначается знаками - и +. Таким образом, маршрут с оценкой 10+ может быть 10c или 10d, и в таблице он должен отображаться между этими оценками.
Поэтому я хочу как-то это уладить.
МВЭ:
\documentclass[12pt,a4paper]{article}
\usepackage{datatool}
\usepackage{filecontents}
\usepackage{longtable}
\begin{filecontents*}{datos.csv}
Route,Grade
Cempasúchil,9
La Gripe, 8
Dopamina infinita, 10b
Casiopea, 11c
El Hombre Avispa, 11b
Tiranosaurio Tex, 11-
Euro Dance, 11a
El Primer Contacto, 12d
\end{filecontents*}
\pagestyle{empty}
\DTLloaddb[keys={Route,Grade}]{datos}{datos.csv}
\DTLsort{Grade=ascending}{datos}
\begin{document}
{\tiny
\noindent
\begin{longtable}{ll}
\bfseries Route & \bfseries Grade \\
\DTLforeach{datos}{%
\pname=Route,\pGrade=Grade}{%
\pname & \pGrade \\
}
\end{longtable}
}
\end{document}
Выход:
Правильный заказ:
8, 9, 10б, 11а, 11-, 11б, 11в, 12г
Идеи решения:
-Разделите число и букву и отсортируйте по двум столбцам. Мне нравится это решение, однако, оно, вероятно, поставит оценки + и - в конце этого числа (я мог бы смириться с его). Также я хотел бы сделать это разделение в datatool, а не из источника.
-Может быть, есть какой-то способ указать индивидуальный порядок. Я бы не возражал против того, чтобы вручную вводить все возможные оценки, их не так уж и много (самый сложный маршрут в мире - 15d, но для гида они варьируются от 8 до 14a). Чтобы решить эту проблему, может быть, изменить или создать пользовательский обработчик (вроде \dtlicompare)?
решение1
Хорошо, мне удалось решить проблему. Возможно, это не самый элегантный способ, но он работает для меня.
Я адаптировал ответ на этот вопрос:Пользовательская сортировка CSV по алфавиту (турецкие символы)
Итак, основная идея такова: вы можете изменить код символа на любой другой, чтобы они сортировались иначе, чем коды UTF8.
Я изменил коды этих символов:
Char ----> New Code
8 ----> 1 (8 always goes first)
9 ----> 2 (9 always goes second)
a ----> 96 (move the a back one code, to put - between a and b)
- ----> 97 (right between a and b)
+ ----> 100 (Right after the c)
d ----> 101 (d is displaced by the d)
Как видите, это решение очень специфично для моей ситуации и не очень хорошо обобщается. Изменения, которые я сделал для символов 8 и 9, были бы проблематичными, если бы существовал маршрут с оценкой 18, так как они были бы размещены перед 10. Но поскольку этой трудности нет (и, вероятно, никогда не будет), это не проблема.
Возможно, такой подход подойдет кому-то, читающему этот вопрос/ответ.
Код(добавить к преамбуле):
\renewcommand*{\dtlsetcharcode}[2]{%
\ifstrequal{#1}{8}%
{%
#2=1\relax
}%
{%
\ifstrequal{#1}{9}%
{%
#2=2\relax
}%
{%
\ifstrequal{#1}{a}%
{%
#2=96\relax
}%
{%
\ifstrequal{#1}{-}%
{%
#2=97\relax
}%
{%
\ifstrequal{#1}{+}%
{%
#2=100\relax
}%
{%
\ifstrequal{#1}{d}%
{%
#2=101\relax
}%
{%
#2=`#1\relax
}%
}%
}%
}%
}%
}%
}
Выход: