diff options
author | Ignace Nyamagana Butera <nyamsprod@gmail.com> | 2014-12-03 09:51:18 +0100 |
---|---|---|
committer | Ignace Nyamagana Butera <nyamsprod@gmail.com> | 2014-12-03 09:51:18 +0100 |
commit | cc9db91e863c02bb831723beb12d154a0f3c1f5f (patch) | |
tree | 2bf2a365a3eed896a4949fa4b05b965ebe91b588 | |
parent | a20b9eb98458d3a52d6709c759babd855cb2732a (diff) | |
download | csv-cc9db91e863c02bb831723beb12d154a0f3c1f5f.zip csv-cc9db91e863c02bb831723beb12d154a0f3c1f5f.tar.gz csv-cc9db91e863c02bb831723beb12d154a0f3c1f5f.tar.bz2 |
fetchAssoc internal code improved
-rw-r--r-- | src/Reader.php | 135 | ||||
-rw-r--r-- | test/ReaderTest.php | 6 |
2 files changed, 81 insertions, 60 deletions
diff --git a/src/Reader.php b/src/Reader.php index d7c2478..f5aa016 100644 --- a/src/Reader.php +++ b/src/Reader.php @@ -73,7 +73,7 @@ class Reader extends AbstractCsv */ public function each(callable $callable) { - $index = 0; + $index = 0; $iterator = $this->query(); $iterator->rewind(); while ($iterator->valid() && true === $callable($iterator->current(), $iterator->key(), $iterator)) { @@ -85,6 +85,38 @@ class Reader extends AbstractCsv } /** + * Return a single column from the CSV data + * + * The callable function will be applied to each value to be return + * + * @param int $column_index field Index + * @param callable $callable a callable function + * + * @throws \InvalidArgumentException If the column index is not a positive integer or 0 + * + * @return array + */ + public function fetchColumn($column_index = 0, callable $callable = null) + { + if (false === filter_var($column_index, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]])) { + throw new InvalidArgumentException( + 'the column index must be a positive integer or 0' + ); + } + + $iterator = $this->query($callable); + $iterator = new MapIterator($iterator, function ($row) use ($column_index) { + if (! array_key_exists($column_index, $row)) { + return null; + } + + return $row[$column_index]; + }); + + return iterator_to_array($iterator, false); + } + + /** * Return a single row from the CSV * * @param int $offset @@ -123,22 +155,18 @@ class Reader extends AbstractCsv * The rows are presented as associated arrays * The callable function will be applied to each Iterator item * - * @param array|int $keys the name for each key member OR the row Index to be - * used as the associated named keys - * @param callable $callable a callable function + * @param array|int $offset_or_keys the name for each key member OR the row Index to be + * used as the associated named keys + * @param callable $callable a callable function * - * @throws \InvalidArgumentException If the submitted keys are not integer or string + * @throws \InvalidArgumentException If the submitted keys are invalid * * @return array */ - public function fetchAssoc($keys = 0, callable $callable = null) + public function fetchAssoc($offset_or_keys = 0, callable $callable = null) { - $keys = $this->formatAssocKeys($keys); - if (! $this->isValidAssocKeys($keys)) { - throw new InvalidArgumentException( - 'Use a flat non empty array with unique string values' - ); - } + $keys = $this->getAssocKeys($offset_or_keys); + $iterator = $this->query($callable); $iterator = new MapIterator($iterator, function ($row) use ($keys) { return static::combineArray($keys, $row); @@ -149,29 +177,54 @@ class Reader extends AbstractCsv /** * Select the array to be used as key for the fetchAssoc method - * @param array|int $keys the assoc key OR the row Index to be used - * as the key index + * @param array|int $offset_or_keys the assoc key OR the row Index to be used + * as the key index * - * @throws \InvalidArgumentException If the row index is invalid + * @throws \InvalidArgumentException If the row index and/or the resulting array is invalid * * @return array */ - protected function formatAssocKeys($keys) + protected function getAssocKeys($offset_or_keys) { - if (is_array($keys)) { - return $keys; - } elseif (false === filter_var($keys, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]])) { - throw new InvalidArgumentException('the column index must be a positive integer or 0'); + $res = $offset_or_keys; + if (! is_array($res)) { + $res = $this->getRow($offset_or_keys); + $this->addFilter(function ($row, $rowIndex) use ($offset_or_keys) { + return is_array($row) && $rowIndex != $offset_or_keys; + }); + } + if (! $this->isValidAssocKeys($res)) { + throw new InvalidArgumentException( + 'Use a flat non empty array with unique string values' + ); } - $this->addFilter(function ($row, $rowIndex) use ($keys) { - return is_array($row) && $rowIndex != $keys; - }); + return $res; + } - $iterator = new LimitIterator($this->getIterator(), $keys, 1); + /** + * Return a single row from the CSV without filtering + * + * @param int $offset + * + * @throws \InvalidArgumentException If the $offset is not valid or the row does not exist + * + * @return array + */ + protected function getRow($offset) + { + if (false === filter_var($offset, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]])) { + throw new InvalidArgumentException('the row index must be a positive integer or 0'); + } + + $iterator = new LimitIterator($this->getIterator(), $offset, 1); $iterator->rewind(); + $res = $iterator->current(); + if (is_null($res)) { + throw new InvalidArgumentException('the specified row does not exist'); + } - return (array) $iterator->current(); + return $res; } /** @@ -213,36 +266,4 @@ class Reader extends AbstractCsv return array_combine($keys, $value); } - - /** - * Return a single column from the CSV data - * - * The callable function will be applied to each value to be return - * - * @param int $column_index field Index - * @param callable $callable a callable function - * - * @throws \InvalidArgumentException If the column index is not a positive integer or 0 - * - * @return array - */ - public function fetchColumn($column_index = 0, callable $callable = null) - { - if (false === filter_var($column_index, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0]])) { - throw new InvalidArgumentException( - 'the column index must be a positive integer or 0' - ); - } - - $iterator = $this->query($callable); - $iterator = new MapIterator($iterator, function ($row) use ($column_index) { - if (! array_key_exists($column_index, $row)) { - return null; - } - - return $row[$column_index]; - }); - - return iterator_to_array($iterator, false); - } } diff --git a/test/ReaderTest.php b/test/ReaderTest.php index 9cea8ca..5257a6b 100644 --- a/test/ReaderTest.php +++ b/test/ReaderTest.php @@ -200,7 +200,7 @@ class ReaderTest extends PHPUnit_Framework_TestCase /** * @expectedException \InvalidArgumentException - * @expectedExceptionMessage the column index must be a positive integer or 0 + * @expectedExceptionMessage the row index must be a positive integer or 0 */ public function testFetchAssocWithInvalidKey() { @@ -222,9 +222,9 @@ class ReaderTest extends PHPUnit_Framework_TestCase /** * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Use a flat non empty array with unique string values + * @expectedExceptionMessage the specified row does not exist */ - public function testFetchAssocWithEmptyArr() + public function testFetchAssocWithInvalidOffset() { $arr = [ ['A', 'B', 'C'], |