我需要读取2个CSV文件数据,合并标题并删除重复的标题。然后,我需要将数据添加到相应的标头中,如果文件中没有标头的数据,则默认为空。
For example:
File one:
'Name', 'Surname', 'Address'
'John', 'Doe', 'example st 123'
File two:
'Surname', 'City', 'Gender'
'Doe', 'Riga', 'Male'
Output File:
'Name', 'Surname', 'Address', 'City', 'Gender'
'John', 'Doe','example st 123', ' ', ' '
' ', 'Doe', ' ', 'Riga', 'Male'
到目前为止,我已经制作了一个给我这些数组的类:
array(5) {
[0]=>
string(4) "Name"
[1]=>
string(7) "Surname"
[2]=>
string(7) "Address"
[4]=>
string(4) "City"
[5]=>
string(6) "Gender"
}
array(2) {
[0]=>
array(1) {
[1]=>
array(3) {
[0]=>
string(4) "John"
[1]=>
string(3) "Doe"
[2]=>
string(10) "Street 123"
}
}
[1]=>
array(1) {
[1]=>
array(3) {
[0]=>
string(3) "Doe"
[1]=>
string(4) "Riga"
[2]=>
string(4) "Male"
}
}
}
这是通过此类完成的:
class Reader
{
private $filePaths = [];
private $headers = [];
private $data = [];
public function add(string $filePath): void
{
$this->filePaths[] = $filePath;
}
public function read(): void
{
foreach ($this->filePaths as $filePath) {
$getData = array_map('str_getcsv', file($filePath));
$this->headers = array_unique(array_merge($this->headers, $getData[0]));
unset($getData[0]);
$this->data[] = $getData;
}
}
public function getData(): array
{
return $this->data;
}
public function getHeaders(): array
{
return $this->headers;
}
任何人都可以帮助我了解如何格式化数据以获得预期结果吗?
目前,我所能得到的就是这个:
Name,Surname,Address,City,Gender
John,Doe,"Street 123"
Doe,Riga,Male
答案 0 :(得分:1)
这是我的解决方法
class Reader
{
public $filePaths = [];
private $headers = [];
private $data = [];
private $originalHeaders = [
];
public function add(string $filePath): void
{
$this->filePaths[] = $filePath;
}
public function read(): void
{
foreach ($this->filePaths as $filePath) {
$fp = fopen($filePath, 'r');
$h = fgetcsv($fp);
$this->originalHeaders[] = $h;
fclose($fp);
$this->headers = array_unique(array_merge($this->headers, $h));
}
print_r($this->originalHeaders);
print_r($this->headers);
$i = 0; // so we know which file we are processing
foreach ($this->filePaths as $i => $filePath) {
$getData = array_map('str_getcsv', file($filePath));
unset($getData[0]);
$this->data = array_merge($this->data, $this->mapData($i, $getData));
}
print_r($this->data);
}
public function output($filename)
{
$fp = fopen($filename, 'w');
fputcsv($fp, $this->headers);
foreach ($this->data as $row) {
fputcsv($fp, $row);
}
fclose($fp);
}
/**
* Map data in column i to column j
*/
private function mapData($n, $data) : array
{
$inputColumns = $this->originalHeaders[$n];
$outputColumns = $this->headers;
$columnIndex = array_flip($outputColumns);
$mappedData = [];
foreach( $data as $i => $row ) {
$workData = array_fill(0, count($this->headers), '');
// Now take each input data and put it in the right place
foreach ($row as $j => $value) {
// Get name of source column
$sourceColumn = $inputColumns[$j];
// Where does that data go in the output
$targetColumnIndex = $columnIndex[$sourceColumn];
// Put the data there
$workData[$targetColumnIndex] = $value;
}
// Store it in the mapped data
$mappedData[] = $workData;
}
return $mappedData;
}
public function getData(): array
{
return $this->data;
}
public function getHeaders(): array
{
return $this->headers;
}
}
$r = new Reader();
$r->filePaths = ['file1.csv', 'file2.csv'];
$r->read();
输入1
Name,Surname,Address
John,Doe,"example st 123"
Natalie,Portman,"1 Starway Ave"
Scotty,Clarke,"Some street Mississippi"
输入2
Surname,City,Gender
Doe,Riga,Male
Ford,"Los Angeles",Male
输出
Name,Surname,Address,City,Gender
John,Doe,"example st 123",,
Natalie,Portman,"1 Starway Ave",,
Scotty,Clarke,"Some street Mississippi",,
,Doe,,,Riga,Male
,Ford,,,"Los Angeles",Male