Skip to content

Commit 4d93eb8

Browse files
author
Florian Eckerstorfer
committed
Merge branch 'master' of github.com:cocur/chain
* 'master' of github.com:cocur/chain: Add support for assoc and reverse sort Add callback option to Sort and SortKeys
2 parents c75ab57 + 9001a5f commit 4d93eb8

File tree

4 files changed

+202
-12
lines changed

4 files changed

+202
-12
lines changed

src/Link/Sort.php

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,60 @@
88
* Class Sort.
99
*
1010
* @author Christoph Rosse
11+
* @author Florian Eckerstorfer <florian@eckerstorfer.co>
1112
*/
1213
trait Sort
1314
{
1415
/**
1516
* Sort a Chain
16-
**.
1717
*
18-
* @param int $sortFlags
18+
* @param int|callable $sortBy
19+
* @param array $options
1920
*
2021
* @return Chain
2122
*/
22-
public function sort($sortFlags = SORT_REGULAR)
23+
public function sort($sortBy = SORT_REGULAR, array $options = [])
2324
{
24-
sort($this->array, $sortFlags);
25+
if (!$sortBy) {
26+
$sortBy = SORT_REGULAR;
27+
}
28+
if ($sortBy && is_callable($sortBy)) {
29+
$this->sortWithCallback($sortBy, $options);
30+
} else {
31+
$this->sortWithFlags($sortBy, $options);
32+
}
2533

2634
return $this;
2735
}
36+
37+
/**
38+
* @param callable $callback
39+
* @param array $options
40+
*/
41+
private function sortWithCallback(callable $callback, array $options = [])
42+
{
43+
if (isset($options['assoc']) && $options['assoc']) {
44+
uasort($this->array, $callback);
45+
} else {
46+
usort($this->array, $callback);
47+
}
48+
}
49+
50+
/**
51+
* @param int $sortFlags
52+
* @param array $options
53+
*/
54+
private function sortWithFlags($sortFlags = SORT_REGULAR, array $options = [])
55+
{
56+
if (!empty($options['assoc']) && !empty($options['reverse'])) {
57+
arsort($this->array, $sortFlags);
58+
} else if (!empty($options['assoc'])) {
59+
asort($this->array, $sortFlags);
60+
} else if (!empty($options['reverse'])) {
61+
rsort($this->array, $sortFlags);
62+
} else {
63+
sort($this->array, $sortFlags);
64+
}
65+
}
2866
}
67+

src/Link/SortKeys.php

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,39 @@
88
* Class SortKeys.
99
*
1010
* @author Christoph Rosse
11+
* @author Florian Eckerstorfer <florian@eckerstorfer.co>
1112
*/
1213
trait SortKeys
1314
{
1415
/**
1516
* Sort a Chain by its keys.
16-
**.
1717
*
18-
* @param int $sortFlags
18+
* @param int|callable $sortBy
19+
* @param array $options
1920
*
2021
* @return Chain
2122
*/
22-
public function sortKeys($sortFlags = SORT_REGULAR)
23+
public function sortKeys($sortBy = SORT_REGULAR, array $options = [])
2324
{
24-
ksort($this->array, $sortFlags);
25+
if ($sortBy && is_callable($sortBy)) {
26+
uksort($this->array, $sortBy);
27+
} else {
28+
$this->sortKeysWithFlags($sortBy, $options);
29+
}
2530

2631
return $this;
2732
}
33+
34+
/**
35+
* @param int $sortFlags
36+
* @param array $options
37+
*/
38+
private function sortKeysWithFlags($sortFlags = SORT_REGULAR, array $options = [])
39+
{
40+
if (!empty($options['reverse'])) {
41+
krsort($this->array, $sortFlags);
42+
} else {
43+
ksort($this->array, $sortFlags);
44+
}
45+
}
2846
}

tests/Link/SortKeysTest.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,72 @@
88
* SortKeysTest.
99
*
1010
* @author Christoph Rosse
11+
* @author Florian Eckerstorfer <florian@eckerstorfer.co>
1112
* @group unit
1213
*/
1314
class SortKeysTest extends PHPUnit_Framework_TestCase
1415
{
1516
/**
1617
* @test
1718
* @covers Cocur\Chain\Link\SortKeys::sortKeys()
19+
* @covers Cocur\Chain\Link\SortKeys::sortKeysWithFlags()
1820
*/
1921
public function sortKeysWithDefaultSorting()
2022
{
2123
/** @var \Cocur\Chain\Link\SortKeys $mock */
2224
$mock = $this->getMockForTrait('Cocur\Chain\Link\SortKeys');
2325
$mock->array = ['lemon' => 1, 'orange' => 2, 'banana' => 3, 'apple' => 4];
2426

25-
$this->assertEquals(['apple' => 4, 'banana' => 3, 'lemon' => 1, 'orange' => 2], $mock->sortKeys()->array);
27+
$this->assertSame(['apple' => 4, 'banana' => 3, 'lemon' => 1, 'orange' => 2], $mock->sortKeys()->array);
2628
}
2729

2830
/**
2931
* @test
3032
* @covers Cocur\Chain\Link\SortKeys::sortKeys()
33+
* @covers Cocur\Chain\Link\SortKeys::sortKeysWithFlags()
3134
*/
3235
public function sortKeysWithAlternativeSortingAlgorithm()
3336
{
3437
/** @var \Cocur\Chain\Link\SortKeys $mock */
3538
$mock = $this->getMockForTrait('Cocur\Chain\Link\SortKeys');
3639
$mock->array = ['111' => 1, '21' => 2, '112' => 3, '22' => 4];
3740

38-
$this->assertEquals(['21' => 2, '22' => 4, '111' => 1, '112' => 3], $mock->sortKeys()->array);
41+
$this->assertSame(['21' => 2, '22' => 4, '111' => 1, '112' => 3], $mock->sortKeys()->array);
42+
}
43+
44+
/**
45+
* @test
46+
* @covers Cocur\Chain\Link\SortKeys::sortKeys()
47+
* @covers Cocur\Chain\Link\SortKeys::sortKeysWithFlags()
48+
*/
49+
public function sortKeysWithDefaultSortingAndReverseOption()
50+
{
51+
/** @var \Cocur\Chain\Link\SortKeys $mock */
52+
$mock = $this->getMockForTrait('Cocur\Chain\Link\SortKeys');
53+
$mock->array = ['lemon' => 1, 'orange' => 2, 'banana' => 3, 'apple' => 4];
54+
55+
$this->assertSame(
56+
['orange' => 2, 'lemon' => 1, 'banana' => 3, 'apple' => 4],
57+
$mock->sortKeys(null, ['reverse' => true])->array
58+
);
59+
}
60+
61+
/**
62+
* @test
63+
* @covers Cocur\Chain\Link\SortKeys::sortKeys()
64+
*/
65+
public function sortKeysWithFunction()
66+
{
67+
/** @var \Cocur\Chain\Link\SortKeys $mock */
68+
$mock = $this->getMockForTrait('Cocur\Chain\Link\SortKeys');
69+
$mock->array = ['kiwi' => 2, 'banana' => 3, 'apple' => 4];
70+
71+
// sort by strlen
72+
$this->assertSame(['kiwi' => 2, 'apple' => 4, 'banana' => 3], $mock->sortKeys(function ($a, $b) {
73+
$a = strlen($a);
74+
$b = strlen($b);
75+
76+
return $a === $b ? 0 : ($a < $b ? -1 : 1);
77+
})->array);
3978
}
4079
}

tests/Link/SortTest.php

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,127 @@
88
* SortTest.
99
*
1010
* @author Christoph Rosse
11+
* @author Florian Eckerstorfer <florian@eckerstorfer.co>
1112
* @group unit
1213
*/
1314
class SortTest extends PHPUnit_Framework_TestCase
1415
{
1516
/**
1617
* @test
1718
* @covers Cocur\Chain\Link\Sort::sort()
19+
* @covers Cocur\Chain\Link\Sort::sortWithFlags()
1820
*/
1921
public function sortWithDefaultSorting()
2022
{
2123
/** @var \Cocur\Chain\Link\Sort $mock */
2224
$mock = $this->getMockForTrait('Cocur\Chain\Link\Sort');
2325
$mock->array = ['lemon', 'orange', 'banana', 'apple'];
2426

25-
$this->assertEquals(['apple', 'banana', 'lemon', 'orange'], $mock->sort()->array);
27+
$this->assertSame(['apple', 'banana', 'lemon', 'orange'], $mock->sort()->array);
2628
}
2729

2830
/**
2931
* @test
3032
* @covers Cocur\Chain\Link\Sort::sort()
33+
* @covers Cocur\Chain\Link\Sort::sortWithFlags()
3134
*/
3235
public function sortWithAlternativeSortingAlgorithm()
3336
{
3437
/** @var \Cocur\Chain\Link\Sort $mock */
3538
$mock = $this->getMockForTrait('Cocur\Chain\Link\Sort');
3639
$mock->array = ['111', '21', '112', '22'];
3740

38-
$this->assertEquals(['21', '22', '111', '112'], $mock->sort(SORT_NUMERIC)->array);
41+
$this->assertSame(['21', '22', '111', '112'], $mock->sort(SORT_NUMERIC)->array);
42+
}
43+
44+
/**
45+
* @test
46+
* @covers Cocur\Chain\Link\Sort::sort()
47+
* @covers Cocur\Chain\Link\Sort::sortWithFlags()
48+
*/
49+
public function sortWithDefaultSortingAndAssocOption()
50+
{
51+
/** @var \Cocur\Chain\Link\Sort $mock */
52+
$mock = $this->getMockForTrait('Cocur\Chain\Link\Sort');
53+
$mock->array = ['lemon', 'orange', 'banana', 'apple'];
54+
55+
$this->assertSame(
56+
[3 => 'apple', 2 => 'banana', 0 => 'lemon', 1 => 'orange'],
57+
$mock->sort(null, ['assoc' => true])->array
58+
);
59+
}
60+
61+
/**
62+
* @test
63+
* @covers Cocur\Chain\Link\Sort::sort()
64+
* @covers Cocur\Chain\Link\Sort::sortWithFlags()
65+
*/
66+
public function sortWithDefaultSortingAndReverseOption()
67+
{
68+
/** @var \Cocur\Chain\Link\Sort $mock */
69+
$mock = $this->getMockForTrait('Cocur\Chain\Link\Sort');
70+
$mock->array = ['lemon', 'orange', 'banana', 'apple'];
71+
72+
$this->assertSame(
73+
['orange', 'lemon', 'banana', 'apple'],
74+
$mock->sort(null, ['reverse' => true])->array
75+
);
76+
}
77+
78+
/**
79+
* @test
80+
* @covers Cocur\Chain\Link\Sort::sort()
81+
* @covers Cocur\Chain\Link\Sort::sortWithFlags()
82+
*/
83+
public function sortWithDefaultSortingAndAssocAndReverseOption()
84+
{
85+
/** @var \Cocur\Chain\Link\Sort $mock */
86+
$mock = $this->getMockForTrait('Cocur\Chain\Link\Sort');
87+
$mock->array = ['lemon', 'orange', 'banana', 'apple'];
88+
89+
$this->assertSame(
90+
[1 => 'orange', 0 => 'lemon', 2 => 'banana', 3 => 'apple'],
91+
$mock->sort(null, ['assoc' => true, 'reverse' => true])->array
92+
);
93+
}
94+
95+
/**
96+
* @test
97+
* @covers Cocur\Chain\Link\Sort::sort()
98+
* @covers Cocur\Chain\Link\Sort::sortWithCallback()
99+
*/
100+
public function sortWithFunction()
101+
{
102+
/** @var \Cocur\Chain\Link\Sort $mock */
103+
$mock = $this->getMockForTrait('Cocur\Chain\Link\Sort');
104+
$mock->array = ['kiwi', 'banana', 'apple'];
105+
106+
// sort by strlen
107+
$this->assertSame(['kiwi', 'apple', 'banana'], $mock->sort(function ($a, $b) {
108+
$a = strlen($a);
109+
$b = strlen($b);
110+
111+
return $a === $b ? 0 : ($a < $b ? -1 : 1);
112+
})->array);
113+
}
114+
115+
/**
116+
* @test
117+
* @covers Cocur\Chain\Link\Sort::sort()
118+
* @covers Cocur\Chain\Link\Sort::sortWithCallback()
119+
*/
120+
public function sortWithFunctionAndAssocOption()
121+
{
122+
/** @var \Cocur\Chain\Link\Sort $mock */
123+
$mock = $this->getMockForTrait('Cocur\Chain\Link\Sort');
124+
$mock->array = ['kiwi', 'banana', 'apple'];
125+
126+
// sort by strlen
127+
$this->assertSame([0 => 'kiwi', 2 => 'apple', 1 => 'banana'], $mock->sort(function ($a, $b) {
128+
$a = strlen($a);
129+
$b = strlen($b);
130+
131+
return $a === $b ? 0 : ($a < $b ? -1 : 1);
132+
}, ['assoc' => true])->array);
39133
}
40134
}

0 commit comments

Comments
 (0)