php按键过滤数组

时间:2012-01-17 17:45:24

标签: php arrays

我有一个类似于以下格式的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

我查看了数组函数,但没有看到任何内容 如果没有某种嵌套循环,我们会这样做。

有更好的方法吗?

2 个答案:

答案 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.