Ordenar conjunto de palabras por longitud

Ordenar conjunto de palabras por longitud

Tengo una gran variedad de palabras que necesito mostrar en orden creciente de longitud. Intenté usar el paquete arraysort y personalizar un comparador.

Mi código simplificado es:

\documentclass{article}                                                                                                        
\usepackage{calc} 
\usepackage{arraysort} 

\newlength{\somelength} 
\newcommand{\showLen}[1]{#1 \setlength{\somelength}{\widthof{#1}}\the\somelength\\} 

\def\IsPositive#1{% 
  TT\fi 
  \ifcat_\ifnum0<0#1 _\else A\fi 
} 
%customised comparator based on example from arraysort manual 
\newcommand{\cmpLen}[2]{% 
  \edef\cmpA{\showLen{#1}}% 
  \edef\cmpB{\showLen{#2}}% 
  \if\IsPositive{\cmpA}% 
  \if\IsPositive{\cmpB}% 
    \arraysortcomparenum{\cmpA}{\cmpB}% 
  \else% 
    \togglefalse {arraysortresequal}% 
    \toggletrue{arraysortresult}% 
  \fi % 
  \else% 
  \if\IsPositive{\cmpB}% 
  \togglefalse{arraysortresequal}% 
  \togglefalse{arraysortresult}% 
  \else% 
  \arraysortcomparestr{\cmpA}{\cmpB}% 
  \fi % 
  \fi % 
} 
\begin{document} 
\newarray{A} 
\readarray{A}{Compulsion&His&Obsession&Girl&Relationship&His}% 
\sortArray[cmpLen]{63}{A} 
\A{1}\A{2}\A{3}\A{4}\A{5} 
\end{document}

Modifiqué el ejemplo "\sortArray con comparador personalizado" en la página 4 del manual de arraysort. Mis modificaciones están en la definición de \cmpAy \cmpBen las que proporciono la longitud calculada con el comando \showLen.

No funciona y el error que se muestra no es claro.

! Undefined control sequence.
\GenericError  ...                                
                                                    #4  \errhelp \@err@     ...
l.37 \A
       {1}\A{2}\A{3}\A{4}\A{5}

¿Por qué mi código no funciona? ¿Existe una mejor manera de hacer esto usando solo LaTeX y sin ordenar previamente mi matriz?

Respuesta1

También necesitabas la opción comparenum. Esto parece hacerlo.

El tiempo de compilación es notablemente excesivo, como si se cargaran cientos de miles de líneas de código... ah ok, es por culpa del \sortArray[cmpLen]{63}{A}OP. Convierte esto en \sortArray[cmpLen]{6}{A}y se compila normalmente.

\documentclass{article}
\usepackage{calc}
\usepackage[comparenum]{arraysort}

\newsavebox\mybox

%\newlength{\somelength}
%\newcommand{\showLen}[1]{#1 \setlength{\somelength}{\widthof{#1}}\the\somelength\\}

\def\IsPositive#1{%
  TT\fi
  \ifcat_\ifnum0<0#1 _\else A\fi
}
%customised comparator based on example from arraysort manual
\newcommand{\cmpLen}[2]{%
  \sbox\mybox{#1}\edef\cmpA{\number\wd\mybox}%
  \sbox\mybox{#2}\edef\cmpB{\number\wd\mybox}%
  \if\IsPositive{\cmpA}%
      \if\IsPositive{\cmpB}%
          \arraysortcomparenum{\cmpA}{\cmpB}%
      \else
          \togglefalse {arraysortresequal}%
          \toggletrue  {arraysortresult}%
      \fi
  \else
      \if\IsPositive{\cmpB}%
          \togglefalse {arraysortresequal}%
          \togglefalse {arraysortresult}%
      \else
          \arraysortcomparenum{\cmpA}{\cmpB}%
      \fi
  \fi
}

\begin{document}
\newarray{A}
\readarray{A}{Compulsion&His&Obsession&Girl&Relationship&His}%

\sortArray[cmpLen]{63}{A}

\A(1)

\A(2)

\A(3)

\A(4)

\A(5)

\A(6)
\end{document}

produce

His
His
Girl
Obsession
Compulsion
Relationship

Respuesta2

Aquí hay una implementación con expl3y l3sort. La variante * ordena en orden inverso; el argumento opcional (el “espacio de coma” predeterminado) es el separador entre elementos en la impresión.

\documentclass{article}
\usepackage{xparse,l3sort}

\ExplSyntaxOn
% \sortwordsbylength has a *-variant (for reverse ordering),
% an optional argument with default value “comma space”
% and a mandatory argument
\NewDocumentCommand{\sortwordsbylength}{ s +O{,~} m }
 {
  \IfBooleanTF{#1}
   {% for decreasing ordering we pass <
    \kees_sort_bylength:nnn { < } { #2 } { #3 }
   }
   {% for increasing order we pass >
    \kees_sort_bylength:nnn { > } { #2 } { #3 }
   }
 }

% some variables
\seq_new:N \l__kees_sort_items_seq
\box_new:N \l__kees_sort_boxa_box
\box_new:N \l__kees_sort_boxb_box

% the main macro
\cs_new_protected:Nn \kees_sort_bylength:nnn
 {% split the input at commas
  \seq_set_split:Nnn \l__kees_sort_items_seq { , } { #3 }
  % sort the sequence according to l3sort
  \seq_sort:Nn \l__kees_sort_items_seq
   {
    \hbox_set:Nn \l__kees_sort_boxa_box { ##1 }
    \hbox_set:Nn \l__kees_sort_boxb_box { ##2 }
    \dim_compare:nTF { \box_wd:N \l__kees_sort_boxa_box #1 \box_wd:N \l__kees_sort_boxb_box }
     { \sort_reversed: }
     { \sort_ordered: }
   }
  % print the sequence, with the stated separator between items
  \seq_use:Nn \l__kees_sort_items_seq { #2 }
 }
\ExplSyntaxOff

\begin{document}

\sortwordsbylength{Compulsion,His,Obsession,Girl,Relationship,His}

\bigskip

\sortwordsbylength*[\par]{Compulsion,His,Obsession,Girl,Relationship,His}

\end{document}

ingrese la descripción de la imagen aquí

información relacionada