Skip to content

Commit

Permalink
Add Collection::transpose method (#8957)
Browse files Browse the repository at this point in the history
* Add transpose method to collection class
* Revert composer.json file
* Remove TransposeIterator subclass
* Remove double lines
* Use standard CakePHP file header
* Handle uneven length array
* Remove debug line
* Remove some space to please lint
* Throw LogicException if arrays do not share the same length
* Use a local variable to keep array value
* Use current() instead of first()
* Use toList() instead of toArray() to preserve all values
  • Loading branch information
dilab authored and markstory committed Jun 17, 2016
1 parent 138f50f commit 9114949
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 1 deletion.
30 changes: 30 additions & 0 deletions src/Collection/CollectionInterface.php
Expand Up @@ -945,4 +945,34 @@ public function isEmpty();
* @return \Iterator
*/
public function unwrap();


/**
* Transpose rows and columns into columns and rows
*
* ### Example:
*
* ```
* $items = [
* ['Products', '2012', '2013', '2014'],
* ['Product A', '200', '100', '50'],
* ['Product B', '300', '200', '100'],
* ['Product C', '400', '300', '200'],
* ]
*
* $transpose = (new Collection($items))->transpose()->toList();
*
* // Returns
* // [
* // ['Products', 'Product A', 'Product B', 'Product C'],
* // ['2012', '200', '300', '400'],
* // ['2013', '100', '200', '300'],
* // ['2014', '50', '100', '200'],
* // ]
*
* ```
*
* @return Collection
*/
public function transpose();
}
21 changes: 20 additions & 1 deletion src/Collection/CollectionTrait.php
Expand Up @@ -576,7 +576,7 @@ public function unfold(callable $transformer = null)
public function through(callable $handler)
{
$result = $handler($this);
return $result instanceof CollectionInterface ? $result: new Collection($result);
return $result instanceof CollectionInterface ? $result : new Collection($result);
}

/**
Expand Down Expand Up @@ -658,4 +658,23 @@ public function _unwrap()
{
return $this->unwrap();
}

/**
* {@inheritDoc}
*
* @return \Cake\Collection
*/
public function transpose()
{
$arrayValue = $this->toList();
$length = count(current($arrayValue));
$result = [];
foreach ($arrayValue as $column => $row) {
if (count($row) != $length) {
throw new \LogicException('Child arrays do not have even length');
}
$result[] = array_column($arrayValue, $column);
}
return new Collection($result);
}
}
60 changes: 60 additions & 0 deletions tests/TestCase/Collection/Iterator/TransposeIteratorTest.php
@@ -0,0 +1,60 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.3.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/

namespace Cake\Test\TestCase\Collection\Iterator;

use Cake\Collection\Collection;
use Cake\TestSuite\TestCase;

class TransposeIteratorTest extends TestCase
{

public function testTranspose()
{
$collection = new Collection([
['Products', '2012', '2013', '2014'],
['Product A', '200', '100', '50'],
['Product B', '300', '200', '100'],
['Product C', '400', '300', '200'],
]);
$transposed = $collection->transpose();
$expected = [
['Products', 'Product A', 'Product B', 'Product C'],
['2012', '200', '300', '400'],
['2013', '100', '200', '300'],
['2014', '50', '100', '200'],
];

$this->assertEquals($expected, $transposed->toList());
}

/**
* Tests that provided arrays do not have even length
*
* @expectedException \LogicException
* @return void
*/
public function testTransposeUnEvenLengthShouldThrowException()
{
$collection = new Collection([
['Products', '2012', '2013', '2014'],
['Product A', '200', '100', '50'],
['Product B', '300'],
['Product C', '400', '300'],
]);

$collection->transpose();
}
}

0 comments on commit 9114949

Please sign in to comment.