从 csv 文件中的表中过滤迭代器的结果

从 csv 文件中的表中过滤迭代器的结果

我是 Lua 新手,我想知道是否有任何方法可以让迭代器从 csv 文件中过滤掉或跳过表中的某些项目。具体来说,我希望迭代器能够获取表中的行,并且仅对列中具有特定标签或参数的行进行操作。以包含以下数据的文件 file.csv 为例:

1, not a prime
2, a prime
3, a prime
4, not a prime
5, a prime
6, not a prime
7, a prime
8, not a prime
9, not a prime

我希望迭代器过滤掉或跳过“素数”条目或“非素数”条目。

我从另一位发帖者那里借用了以下 Lua 代码,该代码定义了将文件内容解释为表格的函数,然后使用通用 for 打印表格。它存储在单独的文件 luacode.lua 中。

function interpretfile()

    local input = io.open('file.csv', 'r')
    primedata = {}

    for line in input:lines() do
        local split = string.explode(line, ",")
        primerow = {}
        primerow.arg1 = split[1]
        primerow.arg2 = split[2]
        table.insert(primedata, primerow)
    end

    input:close()
 end

function printfile()

    for i,p in pairs(primedata) do
       tex.print(string.format("{%s} is{%s} number.\\\\", p.arg1, p.arg2))
    end

end

最后,lua 函数可以在 LaTeX 中进行解释,从而将表格打印到 pdf 中。

\documentclass[12pt]{article}

\directlua{dofile("luacode.lua")}
\def\interpretfile{\directlua{interpretfile()}}
\def\printfile{\directlua{printfile()}}

\begin{document}
\interpretfile
\printfile
\end{document}

有没有办法让 lua 文件中的代码仅打印出 csv 文件的某些行,例如那些具有第二个参数的公共条目的行?除了使用 lua 之外,还有更好的方法来获得我想要实现的结果吗?

答案1

这是编写一个迭代器来过滤某些行的方法解释它们:

filtered_lines = function(input,linefilter)
    local nextline = input:lines()
    return function()
        local line = nextline()
        if not line then return nil end
        --linefilter shall return true (or anaything except nil/false)
        --iff we want to keep the line
        if not linefilter(line) then return nil end
        return line
    end
end

only_primes = function(line)
    return line:match(", a prime")
end

--use as:
for line in filtered_lines(input,only_primes) do
    ...
end

答案2

这是一种在 TeX 中起作用的方法,使用listofitemsreadarray读取文件,排序成数组,然后筛选数组。

\documentclass{article}
\begin{filecontents*}[overwrite]{data.txt}
1, not a prime
2, a prime
3, a prime
4, not a prime
5, a prime
6, not a prime
7, a prime
8, not a prime
9, not a prime
\end{filecontents*}
\usepackage{readarray}
%\usepackage{listofitems}% INCLUDED WITH readarray
\newcommand\findrecords[3]{%
  \def\CMP{#1}%
  \def#3{}%
  \foreachitem\z\in#2[]{%
    \itemtomacro#2[\zcnt,2]\tmp%
    \ifx\tmp\CMP
      \if\relax#3\relax\else\edef#3{#3,}\fi%
      \edef#3{#3#2[\zcnt,1]}%
    \fi
  }%
}
\begin{document}
\readarraysepchar{\\}
\readdef{data.txt}\mydatadef% READ \\ SEPARATED RECORDS INTO \mydatadef
\setsepchar{\\/,}
\ignoreemptyitems
\readlist*\mydata{\mydatadef}% PLACE DATA INTO \mydata ARRAY

\findrecords{a prime}{\mydata}{\APlist}
Primes: \APlist

\findrecords{not a prime}{\mydata}{\NAPlist}
Not primes: \NAPlist
\end{document}

在此处输入图片描述

相关内容