排序表格列

排序表格列

假设我有一张包含两列的表格。我该如何根据第一列对行进行排序?在 latex 中可以吗?如果我在另一个应用程序(如 MS Excel)中执行此操作,我可以将工作表中的数据导入表格吗?
如果您能建议我一种处理这种排序的方法,我会非常高兴,越简单越好!顺便说一句,我看了按字母数字列表排序根本就没得到它!

答案1

我毫不怀疑这datatool是可行的方法。但是,可以使用我对排序问题的回答中的代码来执行此操作。

您需要定义一个仅比较第一列的新比较器。此特定实现需要具有行顶级扩展的东西。例如,您可以为每一行定义一个宏。

\def\rowi  {C & foo & qwer \\}
\def\rowii {A & bar & asdf \\}
\def\rowiii{B & baz & zxcv \\}

目标是能够编写以下内容来获取排序后的行。

\begin{tabular}{lll}
\toprule
Letters & Metasyntatic variables & Gibberish\\
\midrule
\sortfirstcol{\rowi\rowii\rowiii}
\bottomrule
\end{tabular}

具体来说,\sortfirstcol{\rowi\rowii\rowiii}应该扩展为已排序的行。与 一样\sortalpha\sortfirstcol只是一个简单的宏,\sort以比较器\sort@firstcol作为其第一个参数进行扩展。

\newcommand*\sortfirstcol{\sort\sort@firstcol} 

比较器并不复杂,但它确实需要提取每个参数的第一列。为此,我们使用辅助宏。为了与原始答案的精神保持一致,此版本是可扩展的。

\def\sort@firstcol#1#2{%
    \expandafter\expandafter\expandafter
        \sort@fc@helper\expandafter#1#2#1#2%
}

\def\sort@fc@helper#1&#2\\#3&#4\\#5#6#7{%
    \ifnumcomp{\pdfstrcmp{#1}{#3}}<{0}
    {#7{#5}{#6}}% else
    {#7{#6}{#5}}%
}

s\expandafter将一次性扩展前两个参数。例如,如果比较器被“调用”为\sort@firstcol{\rowi}{\rowii}{...},则它将扩展为

\sort@fc@helper C & foo & qwer \\A & bar & asdf \\\rowi\rowii{...}

因此#1将是标记“C”,#3将是“A”,#5将是\rowi#6将是\rowii,最后#7将是{...}传递给比较器的延续。

从这里开始,它与 相同\sort@alpha:它比较#1#3,并将#5和传递#6到延续。

最后,由于行的表示,\sortend\sortoutput宏应该设置为仅扩展到它们的参数:

\newcommand*\sortoutput[1]{#1}
\newcommand*\sortend[1]{#1}

以下是使用上述代码和上一个答案中的代码的完整示例。

\documentclass{article}
\usepackage{etoolbox}
\usepackage{booktabs}
\makeatletter
% #1 - comparator
% #2 - token list to sort
\newcommand\sort[2]{%
        \ifstrempty{#2}
        {}% else
        {%
                \sort@begin#1{}#2\sort@s\sort@begin
        }%
}

% helpers
\def\sort@s{\sort@s}
\def\ifsort@s#1{%
        \ifx\sort@s#1%
                \expandafter\@firstoftwo
        \else
                \expandafter\@secondoftwo
        \fi
}

% #1 - comparator
% #2 - tokens processed so far
% #3 - smallest token so far
% #4 - rest of the list
\def\sort@begin#1#2#3#4\sort@begin{%
        \ifsort@s{#4}
        {%
                \sortend{#3}%
                \sort#1{#2}%
        }% else
        {%
                \sort@go#1{#2}{#3}#4\sort@go
        }%
}

%     #1 - comparator
% #2 - tokens processed so far
% #3 - smallest token so far
% #4 - token under consideration
% #5 - rest of the list
\def\sort@go#1#2#3#4#5\sort@go{%
        #1{#3}{#4}{\sort@output#1{#2}{#5}}%
}
% #1 - comparator
% #2 - tokens processed so far
% #3 - rest of the list
% #4 - smaller of the two tokens
% #5 - larger of the two tokens
\def\sort@output#1#2#3#4#5{%
        \ifsort@s{#3}
        {%
                \sortoutput{#4}%
                \sort#1{#2{#5}}%
        }% else
        {%
                \sort@begin#1{#2{#5}}{#4}#3\sort@begin
        }%
}

\def\sort@numlt#1#2#3{%
        \ifnumcomp{#1}<{#2}
        {#3{#1}{#2}}% else
        {#3{#2}{#1}}%
}

\def\sort@numgt#1#2#3{%
        \ifnumcomp{#1}>{#2}
        {#3{#1}{#2}}% else
        {#3{#2}{#1}}%
}

\def\sort@alpha#1#2#3{%
        \ifnumcomp{\pdfstrcmp{#1}{#2}}<{0}
        {#3{#1}{#2}}% else
        {#3{#2}{#1}}%
}

\def\sort@firstcol#1#2{%
    \expandafter\expandafter\expandafter
        \sort@fc@helper\expandafter#1#2#1#2%
}

\def\sort@fc@helper#1&#2\\#3&#4\\#5#6#7{%
    \ifnumcomp{\pdfstrcmp{#1}{#3}}<{0}
    {#7{#5}{#6}}% else
    {#7{#6}{#5}}%
}

\newcommand*\sortnumlt{\sort\sort@numlt}
\newcommand*\sortnumgt{\sort\sort@numgt}
\newcommand*\sortalpha{\sort\sort@alpha}
\newcommand*\sortfirstcol{\sort\sort@firstcol}
\makeatother

% Change these to change out the sort outputs.
\newcommand*\sortoutput[1]{#1}
\newcommand*\sortend[1]{#1}

\begin{document}

\def\rowi  {C & foo & qwer \\}
\def\rowii {A & bar & asdf \\}
\def\rowiii{B & baz & zxcv \\}

\begin{tabular}{lll}
\toprule
Letters & Metasyntatic variables & Gibberish\\
\midrule
\sortfirstcol{\rowi\rowii\rowiii}
\bottomrule
\end{tabular}

\end{document}

最后,我应该指出,这种表示(即,将行作为宏)不是必需的。由于\sort处理其参数的方式,可以轻松编写一个比较器,允许编写以下内容。

\sortfirstcol{%
    {C & foo & qwer}%
    {A & bar & asdf}%
    {B & baz & zxcv}%
}
\def\sortoutput#1{#1\\}
\def\sortend#1{#1\\}

也许我应该这么做。比较器会稍微简单一些。

此外,在实施过程中,第一列开头或结尾的空格很重要。人们可能也会处理这个问题。

答案2

datatool该包有很多函数可以对数据进行排序和分析。

答案3

有许多很好的技术可以将 Excel 或其他电子表格数据传输到 latex 源中。请参阅此答案这里。如果您在 Mac 上使用 TeXShop,还有一个内置的“粘贴电子表格单元格”宏可以完成这个操作。

相关内容