summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgnace Nyamagana Butera <nyamsprod@gmail.com>2014-12-03 09:51:18 +0100
committerIgnace Nyamagana Butera <nyamsprod@gmail.com>2014-12-03 09:51:18 +0100
commitcc9db91e863c02bb831723beb12d154a0f3c1f5f (patch)
tree2bf2a365a3eed896a4949fa4b05b965ebe91b588
parenta20b9eb98458d3a52d6709c759babd855cb2732a (diff)
downloadcsv-cc9db91e863c02bb831723beb12d154a0f3c1f5f.zip
csv-cc9db91e863c02bb831723beb12d154a0f3c1f5f.tar.gz
csv-cc9db91e863c02bb831723beb12d154a0f3c1f5f.tar.bz2
fetchAssoc internal code improved
-rw-r--r--src/Reader.php135
-rw-r--r--test/ReaderTest.php6
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'],