我有一个类似于以下格式的csv文件。有 实际文件中没有列标题 - 为了清楚起见,这里显示了它们。
id|user|date|description
0123456789|115|2011-10-12:14:29|bar rafael
0123456789|110|2012-01-10:01:34|bar rafael
0123456902|120|2011-01-10:14:55|foo fighter
0123456902|152|2012-01-05:07:17|foo fighter
0123456902|131|2011-11-21:19:48|foo fighter
对于每个ID,我只需要保留最新的记录,然后写 结果返回文件。
结果应为:
0123456789|110|2012-01-10:01:34|bar rafael
0123456902|152|2012-01-05:07:17|foo fighter
我查看了数组函数,但没有看到任何内容 如果没有某种嵌套循环,我们会这样做。
有更好的方法吗?
答案 0 :(得分:1)
const F_ID = 0;
const F_USER = 1;
const F_DATE = 2;
const F_DESCRIPTION = 3;
$array = array();
if (($handle = fopen('test.csv', 'r')) !== FALSE) {
while (($data = fgetcsv($handle, 1000, '|')) !== FALSE) {
if (count($data) != 4)
continue; //skip lines that have a different number of cells
if (!array_key_exists($data[F_ID], $array)
|| strtotime($data[F_DATE]) > strtotime($array[$data[F_ID]][F_DATE]))
$array[$data[F_ID]] = $data;
}
}
你将在$array
中拥有你想要的东西。您可以使用fputcsv
编写它。
请注意。我没有测试这段代码,它的目的是提供一个如何工作的基本概念。
我们的想法是将所需的行存储到$array
中,使用第一个值(ID)作为键。这样,在您阅读的每一行上,您都可以检查您是否已经拥有该ID的记录,并且只有在日期更新的情况下才替换它。
答案 1 :(得分:1)
每次遇到新ID时,请将其放入$out
数组中。如果id已存在,则在值较新时覆盖它。类似的东西:
$in_array = file('myfile.txt');
$out_array = array();
$fields = array('id', 'user', 'date', 'description');
foreach($in_array as $line) {
$row = array_combine($fields, explode('|', $line) );
//New id? Just add it.
if ( !isset($out_array[ $row['id'] ]) ) {
$out_array[ $row['id'] ] = $row;
}
//Existing id? Overwrite if newer.
else if (strcmp( $row['date'], $out_array[ $row['id'] ]['date'] ) > 0 ) {
$out_array[ $row['id'] ] = $row;
}
//Otherwise ignore
}
//$out_array now has the newest row for each id, keyed by id.