Skip to content

Commit

Permalink
implementing detectDelimiter #16
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Mar 5, 2014
1 parent ef58410 commit 3bcd75c
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/AbstractCsv.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
use SplFileObject;
use SplTempFileObject;
use InvalidArgumentException;
use LimitIterator;
use CallbackFilterIterator;

/**
* A abstract class to enable basic CSV manipulation
Expand Down Expand Up @@ -209,6 +211,40 @@ public function getDelimiter()
return $this->delimiter;
}

/**
* Detect the CSV file delimiter
*
* @param integer $nbRows
* @param array $additionals additional delimiters
*
* @return string
*/
public function detectDelimiter($nbRows = 1, array $additionals = [])
{
$nbRows = filter_var($nbRows, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]);
if (! $nbRows) {
throw new InvalidArgumentException('`$nbRows` must be a valid positive integer');
}
$additionals = array_filter($additionals, function ($str) {
return 1 == mb_strlen($str);
});
$delimiters = [',', ';', "\t"];
$delim = array_unique(array_merge($delimiters, $additionals));
$iterator = new CallbackFilterIterator(new LimitIterator($this->csv, 0, $nbRows), function ($row) {
return is_array($row) && count($row) > 1;
});
$origDelimiter = $this->getDelimiter();
$res = array_fill_keys($delimiters, null);
foreach ($delimiters as $delim) {
$iterator->setCsvControl($delim);
$res[$delim] = count(iterator_to_array($iterator, false));
}
$this->setDelimiter($origDelimiter);
arsort($res, SORT_NUMERIC);

return array_keys(array_filter($res));
}

/**
* set the field enclosure
*
Expand Down
19 changes: 19 additions & 0 deletions test/CsvTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,25 @@ public function testDelimeter()
$this->csv->setDelimiter('foo');
}

/**
* @expectedException InvalidArgumentException
*/
public function testDetectDelimiter()
{
$this->assertSame($this->csv->detectDelimiter(), [',']);

$csv = new Writer(new SplTempFileObject);
$csv->setDelimiter(';');
$csv->insertOne(['toto', 'tata', 'tutu']);
$csv->setDelimiter(',');
$csv->insertOne(['toto', 'tata', 'tutu']);
$csv->insertOne(['toto', 'tata', 'tutu']);
$csv->insertOne(['toto', 'tata', 'tutu']);

$this->assertSame($csv->detectDelimiter(5, ['toto', '|']), [',', ';']);
$csv->detectDelimiter(-4);
}

/**
* @expectedException InvalidArgumentException
*/
Expand Down

0 comments on commit 3bcd75c

Please sign in to comment.