Skip to content

Commit

Permalink
fetchAssoc internal code improved
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Dec 3, 2014
1 parent a20b9eb commit cc9db91
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 60 deletions.
135 changes: 78 additions & 57 deletions src/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function query(callable $callable = null)
*/
public function each(callable $callable)
{
$index = 0;
$index = 0;
$iterator = $this->query();
$iterator->rewind();
while ($iterator->valid() && true === $callable($iterator->current(), $iterator->key(), $iterator)) {
Expand All @@ -84,6 +84,38 @@ public function each(callable $callable)
return $index;
}

/**
* 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
*
Expand Down Expand Up @@ -123,22 +155,18 @@ public function fetchAll(callable $callable = null)
* 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);
Expand All @@ -149,29 +177,54 @@ public function fetchAssoc($keys = 0, callable $callable = null)

/**
* 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;
}

/**
Expand Down Expand Up @@ -213,36 +266,4 @@ protected static function combineArray(array $keys, array $value)

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);
}
}
6 changes: 3 additions & 3 deletions test/ReaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public function testFetchAssocKeyFailure()

/**
* @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()
{
Expand All @@ -222,9 +222,9 @@ public function testFetchAssocWithInvalidKey()

/**
* @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'],
Expand Down

0 comments on commit cc9db91

Please sign in to comment.