为了账号安全,请及时绑定邮箱和手机立即绑定

删除 CSV 文件特定列中具有重复值的行

删除 CSV 文件特定列中具有重复值的行

PHP
MM们 2023-08-26 10:06:40
我这里有 data.csv:id: 10, location: Canada, people: 12id: 10, location: United States, people: 15id: 15, location: England, people: 19id: 16, location: India, people: 20id: 16, location: Germany, people: 9我希望它使用 PHP 输出:id: 10, location: Canada, people: 12id: 15, location: England, people: 19id: 16, location: India, people: 20通过删除第一列中具有相同值的行。我怎样才能做到这一点?(我是 PHP 新手,真的不知道在这里要做什么;我尝试了其他人为类似问题制作的一些脚本,但它们似乎不起作用)我更希望它回显结果而不是覆盖或创建一个新文件。
查看完整描述

2 回答

?
杨魅力

TA贡献1811条经验 获得超5个赞

使用 fgetcsv 逐行读取 csv 并创建数组,其中“:”后面的内容是键,后面的内容是值。


然后您可以删除重复项。


当您只有数据时,您需要构建 csv 字符串。您可以直接使用它或将其存储在输出 csv 文件中。


<?php


$handle = fopen("data.csv", "r");


// parse csv line by line and create data array with its information

$data = [];

while (($row = fgetcsv($handle)) !== false) {

  $newRow = [];

  foreach ($row as $field) {

     $parts = explode(':', $field);

     $key = trim($parts[0]);

     $value = trim($parts[1]);


     $newRow[$key] = $value;

  }


  $data[] = $newRow;

}


// iterate data and remove duplicate ids - keep only first id occurence

$indexedData = [];

foreach ($data as $row) {

  if (!isset($indexedData[$row['id']])) {

    $indexedData[$row['id']] = $row;

  }

}


var_dump($indexedData);


// create csv string with new data

$result = '';

foreach ($indexedData as $row) {

  $fields = [];

  foreach ($row as $key => $value) {

    $fields[] = $key.': '.$value;

  }

  $result .= implode(', ', $fields).PHP_EOL;

}


var_dump($result);

$索引数据:


array(3) {

  [10]=>

  array(3) {

    ["id"]=>

    string(2) "10"

    ["location"]=>

    string(6) "Canada"

    ["people"]=>

    string(2) "12"

  }

  [15]=>

  array(3) {

    ["id"]=>

    string(2) "15"

    ["location"]=>

    string(7) "England"

    ["people"]=>

    string(2) "19"

  }

  [16]=>

  array(3) {

    ["id"]=>

    string(2) "16"

    ["location"]=>

    string(5) "India"

    ["people"]=>

    string(2) "20"

  }

}

$结果:


string(111) "id: 10, location: Canada, people: 12

id: 15, location: England, people: 19

id: 16, location: India, people: 20

"

或者,如果您不关心 csv 中的数据(例如您不需要人数统计等),这里是更简单的版本:


<?php


$handle = fopen("data.csv", "r");


$data = [];

while (($row = fgetcsv($handle)) !== false) {

  if (!isset($data[$row[0]])) {

    $data[$row[0]] = $row;

  }

}


$result = '';

foreach ($data as $row) {

  $result .= implode(',', $row).PHP_EOL;

}


var_dump($result);

$结果是一样的。


查看完整回答
反对 回复 2023-08-26
?
守候你守候我

TA贡献1802条经验 获得超10个赞

您实际上不需要解析整行数据。一次preg_replace()调用即可删除后来出现的重复行。


以下模式仅用于处理彼此相邻的重复行。它不是为了处理由非重复项分隔的重复项而构建的。


代码:(演示


echo preg_replace(

         '/(^id: (\d+),.+)(?:\Rid: \2,.+)+/m',

         '$1',

         file_get_contents('data.csv')

     );

或者,您可以使用单个循环并维护一个查找数组来确定之前是否已回显 id。


即使重复行被非重复行分隔开,这也将起作用。


代码:(演示


foreach (explode(PHP_EOL, $csv) as $line) {

    $firstColumn = strtok($line, ',');

    if (!isset($lookup[$firstColumn])) {

        echo $line . PHP_EOL;

        $lookup[$firstColumn] = true;

    }

}


查看完整回答
反对 回复 2023-08-26
  • 2 回答
  • 0 关注
  • 111 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信