我正在导入一个包含3列的CSV,其中一列可能有重复的记录。
我要检查两件事:
1. The field 'NAME' is not null and is a string
2. The field 'ID' is unique
到目前为止,我正在解析CSV文件,并检查1. (NAME is valid)
,如果失败,它只会中断while循环并停止。
我想问题是,我如何检查ID
是否唯一?
我有以下字段:
NAME, ID,
Bob, 1,
Tom, 2,
James, 1,
Terry, 3,
Joe, 4,
这将输出类似“第3行的重复ID”
由于
P.S此CSV文件包含更多列,可以有大约100,000条记录。我已将其简化为特定原因以解决重复的列/字段
由于
答案 0 :(得分:1)
<?php
$cnt = 0;
$arr=array();
if (($handle = fopen("1.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num=count($data);
$cnt++;
for ($c=0; $c < $num; $c++) {
if(is_numeric($data[$c])){
if (array_key_exists($data[$c], $arr))
$arrdup[] = "duplicate value at ".($cnt-1);
else
$arr[$data[$c]] = $data[$c-1];
}
}
}
fclose($handle);
}
print_r($arrdup);
答案 1 :(得分:0)
我假设某种类型的设计被剥离了CSV部分,但这个想法将保持不变:
<?php
/* Let's make an array of 100,000 rows (Be careful, you might run into memory issues with this, issues you won't have with a CSV read line by line)*/
$arr = [];
for ($i = 0; $i < 100000; $i++)
$arr[] = [rand(0, 1000000), 'Hey'];
/* Now let's have fun */
$ids = [];
foreach ($arr as $line => $couple) {
if ($ids[$couple[0]])
echo "Id " . $couple[0] . " on line " . $line . " already used<br />";
else
$ids[$couple[0]] = true;
}
?>
100,000行并不是那么多,这就足够了。 (它在我的地方跑了3秒钟。)
编辑:正如所指出的,in_array
的效率低于密钥查找。我因此更新了我的代码。
答案 2 :(得分:0)
试一试:
$row = 1;
$totalIDs = array();
if (($handle = fopen('/tmp/test1.csv', "r")) !== FALSE)
{
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
$name = '';
if (isset($data[0]) && $data[0] != '')
{
$name = $data[0];
if (is_numeric($data[0]) || !is_string($data[0]))
echo "Name is not a string for row $row\n";
}
else
{
echo "Name not set for row $row\n";
}
$id = '';
if (isset($data[1]))
{
$id = $data[1];
}
else
{
echo "ID not set for row $row\n";
}
if (isset($totalIDs[$id]))
echo "Duplicate ID on line $row\n";
else
$totalIDs[$id] = 1;
$row++;
}
fclose($handle);
}
答案 3 :(得分:0)
ID是否按可能重复的方式排序,或者是随机分布的?
如果它们已经排序并且列表中没有漏洞(1,2,3,4可以; 1,3,4,7不正常)那么只需存储您读取的最后一个ID并将其与当前ID。如果当前等于或小于最后,那么它就是重复。
如果ID是随机顺序,那么您必须将它们存储在一个数组中。你有多种选择。如果你有足够的内存,只需将ID存储为普通PHP数组中的密钥并检查它:
$ids = array();
// ... read and parse CSV
if (isset($ids[$newId])) {
// you have a duplicate
} else {
$ids[$newId] = true; // new value, not a duplicate
}
PHP数组是哈希表,并且具有非常快速的键查找。将ID存储为值并使用in_array()
进行搜索会在阵列增长时损害性能。
如果必须保存内存,并且知道要从CSV读取的行数,则可以使用SplFixedArray
而不是普通的PHP数组。重复检查将与上述相同。