我是 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 中起作用的方法,使用listofitems
和readarray
读取文件,排序成数组,然后筛选数组。
\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}