単語の配列を長さ順に並べ替える

単語の配列を長さ順に並べ替える

単語の長い配列があり、それを長さの昇順で表示する必要があります。パッケージ arraysort を使用して比較器をカスタマイズしようとしました。

簡略化したコードは次のとおりです。

\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}

arraysort マニュアルの 4 ページにある「カスタム比較器を使用した \sortArray」の例を変更しました。変更点は の定義\cmpAと、\cmpBコマンド \showLen を使用して計算された長さを提供する部分です。

動作せず、表示されるエラーが明確ではありません。

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

なぜ私のコードが機能しないのですか? LaTeX のみを使用して配列を事前にソートせずにこれを行うより良い方法はありますか?

答え1

オプションも必要でしたcomparenum。これで解決するようです。

コンパイル時間は、数十万行のコードがロードされたかのように、著しく長すぎます... ああ、わかりました。これは\sortArray[cmpLen]{63}{A}OP のためです。これを に変更する\sortArray[cmpLen]{6}{A}と、正常にコンパイルされます。

\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}

生産する

His
His
Girl
Obsession
Compulsion
Relationship

答え2

expl3以下はとを使用した実装ですl3sort。 * バリアントは逆順にソートします。オプションの引数 (デフォルトは「カンマ スペース」) は、出力内の項目間の区切り文字です。

\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}

ここに画像の説明を入力してください

関連情報