Skip to content
Permalink
Browse files

Add Collection::transpose method (#8957)

* 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 9114949b48679f1db90824727d561fbb009577d1
@@ -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();
}
@@ -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);
}
/**
@@ -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);
}
}
@@ -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.
You can’t perform that action at this time.