如何在 League Reader 中跳过重复的(按标题)CSV 列?

问题描述 投票:0回答:3

我正在使用

league/csv:^9.6
(9.6.2)。

我需要解析包含大量列(150+)的 CSV 文件,并提取其中的少量列(8)。这些列在偏移量方面并不固定(位置未知),但它们具有稳定的唯一标题 - 所以我想通过标题而不是偏移量来选择它们。

但问题是:库抛出有关重复标头的异常。有没有解决方案如何跳过它们并正确解析所有其他行?

或者有什么解决方法可以在使用这个库之前将它们从文件中删除吗?这些重复项的位置和数量事先是未知的。

谢谢!

php csv parsing thephpleague
3个回答
3
投票

您可以自己映射列名称。不要设置标题偏移量,这将使 League 返回带有整数键的行。

然后使用包含所需列名的数组来构建索引的映射。我做了一个小工作示例:

测试.csv

name;;;age;;;;a;a;a;;;;
John;;;32;;;;;;;;;;
Jane;;;28;;;;;;;;;;

测试.php

//The columns you want to extract
$columns = ['name', 'age'];

$reader = Reader::createFromPath('test.csv', 'r+');
$reader->setDelimiter(';');
$grab = [];

//Find the indexes
foreach ($reader->fetchOne() as $index => $column) {
    if (in_array($column, $columns)) {
        $grab[$column] = $index;
    }
}

foreach ($reader->getRecords() as $i => $row) {
    if ($i == 0) {
        continue;
    }

    $filteredRow = [];
    foreach ($grab as $column => $index) {
        $filteredRow[$column] = $row[$index];
    }

    //$filteredRow now contains the needed columns
    var_dump($filteredRow);
}

输出:

array(2) {
  ["name"]=> string(4) "John"
  ["age"]=> string(2) "32"
}
array(2) {
  ["name"]=> string(4) "Jane"
  ["age"]=> string(2) "28"
}

1
投票

简化版!

$columns = ['name', 'age'];

$validColumns = array_intersect($reader->fetchOne(0), $columns);
$validIndices = array_flip(array_keys($validColumns));

foreach ($reader->getRecords() as $i => $row) {
    if ($i > 0) {
        $csvArray[] = array_combine( $validColumns, array_intersect_key( $row, $validIndices ));
    }
}

0
投票
use League\Csv\Reader;
use League\Csv\Statement;

$reader = Reader::createFromString($csv);
$reader->setDelimiter(';');
$reader->setHeaderOffset(0);
$reader->setEscape('');

$records = Statement::create()
    ->process($reader, array_filter($reader->getHeader()));
© www.soinside.com 2019 - 2024. All rights reserved.