Skip to content

Commit c8e07c0

Browse files
committed
Merge pull request hexlet-components#2 from LionsHead/master
add List
2 parents 70c375e + f44dbf7 commit c8e07c0

File tree

6 files changed

+245
-20
lines changed

6 files changed

+245
-20
lines changed

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,39 @@
33
[![Build Status](https://travis-ci.org/hexlet-components/php-pairs.svg?branch=master)](https://travis-ci.org/hexlet-components/php-pairs)
44
[![Code Climate](https://codeclimate.com/github/hexlet-components/php-pairs/badges/gpa.svg)](https://codeclimate.com/github/hexlet-components/php-pairs)
55
[![Issue Count](https://codeclimate.com/github/hexlet-components/php-pairs/badges/issue_count.svg)](https://codeclimate.com/github/hexlet-components/php-pairs)
6+
7+
8+
### Functions for working with Pairs
9+
```
10+
use function Pairs\cons;
11+
use function Pairs\car;
12+
use function Pairs\cdr;
13+
use function Pairs\toString;
14+
```
15+
16+
### Functions for working with Lists
17+
```
18+
use function Lists\length;
19+
use function Lists\reverse;
20+
use function Lists\map;
21+
use function Lists\filter;
22+
use function Lists\reduce;
23+
```
24+
### example
25+
\# 1
26+
```
27+
$pair = cons(1, 2);
28+
29+
$one = Pairs\car($pair); // $one = 1;
30+
$two = Pairs\cdr($pair) // $two = 2;
31+
```
32+
\# 2
33+
```
34+
$list = cons(1, cons(2, cons(3, cons(4, cons(5, cons(6, null))))));
35+
$length = length($list); // $length = 6;
36+
37+
$filter = filter(function ($x) {
38+
return $x % 2 == 0;
39+
}, $list);
40+
$result = toString($filter); \\ $result = "(2, 4, 6)";
41+
```

composer.json

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
{
2-
"name": "hexlet\\pairs",
3-
"description": "",
4-
"license": "MIT",
5-
"keywords": ["pairs"],
6-
"authors": [
7-
{
8-
"name": "Kirill Mokevnin",
9-
"email": "[email protected]"
2+
"name": "hexlet\\pairs",
3+
"description": "",
4+
"license": "MIT",
5+
"keywords": ["pairs"],
6+
"authors": [
7+
{
8+
"name": "Kirill Mokevnin",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"require": {},
13+
"require-dev": {
14+
"phpunit/phpunit": "*",
15+
"squizlabs/php_codesniffer": "2.*"
16+
},
17+
"autoload": {
18+
"files": [
19+
"src/Pairs.php",
20+
"src/Lists.php"
21+
]
1022
}
11-
],
12-
"require": {},
13-
"require-dev": {
14-
"phpunit/phpunit": "*",
15-
"squizlabs/php_codesniffer": "2.*"
16-
},
17-
"autoload": {
18-
"files": [
19-
"src/Pairs.php"
20-
]
21-
}
2223
}

phpunit.xml.dist

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit backupGlobals="false"
4+
backupStaticAttributes="false"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false"
11+
syntaxCheck="false"
12+
bootstrap="vendor/autoload.php"
13+
>
14+
<testsuites>
15+
<testsuite name="Test Suite">
16+
<directory>./tests/</directory>
17+
</testsuite>
18+
</testsuites>
19+
</phpunit>

src/Lists.php

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
namespace Lists;
4+
5+
use function Pairs\cons;
6+
use function Pairs\car;
7+
use function Pairs\cdr;
8+
use function Pairs\toString;
9+
10+
/**
11+
* Applies callable function $func to list $list
12+
* @param callable $func function
13+
* @param callable $list list
14+
* @return result list
15+
*/
16+
function map(callable $func, callable $list)
17+
{
18+
$map = function ($items, $acc) use (&$map, $func) {
19+
if (is_null($items)) {
20+
return reverse($acc);
21+
}
22+
return $map(cdr($items), cons($func(car($items)), $acc));
23+
};
24+
25+
return $map($list, null);
26+
}
27+
28+
/**
29+
* Filters list $list using callable function $func
30+
* @param callable $func function
31+
* @param callable $list list
32+
* @return result list
33+
*/
34+
function filter(callable $func, callable $list)
35+
{
36+
$map = function ($func, $items) use (&$map) {
37+
if ($items === null) {
38+
return null;
39+
} else {
40+
$curr = car($items);
41+
$rest = $map($func, cdr($items));
42+
// filter
43+
return $func($curr) ? cons($curr, $rest) : $rest;
44+
}
45+
};
46+
47+
return $map($func, $list);
48+
}
49+
50+
/**
51+
* Collapses the list $list using callable function $func
52+
* @param callable $func function
53+
* @param callable $list list
54+
* @param mixed $acc
55+
* @return result
56+
*/
57+
function reduce(callable $func, callable $list, $acc = null)
58+
{
59+
$iter = function ($items, $acc) use (&$iter, $func) {
60+
return is_null($items) ? $acc : $iter(cdr($items), $func(car($items), $acc));
61+
};
62+
63+
return $iter($list, $acc);
64+
}
65+
66+
/**
67+
* Concatenates two lists
68+
* @param pair $list1
69+
* @param pair $list2
70+
* @return new list
71+
*/
72+
function append(callable $list1, callable $list2)
73+
{
74+
if ($list1 === null) {
75+
return $list2;
76+
} else {
77+
return cons(car($list1), append(cdr($list1), $list2));
78+
}
79+
}
80+
81+
/**
82+
* Reverse list $list
83+
* @param callable $list list
84+
* @return result
85+
*/
86+
function reverse(callable $list)
87+
{
88+
$iter = function ($items, $acc) use (&$iter) {
89+
return is_null($items) ? $acc : $iter(cdr($items), cons(car($items), $acc));
90+
};
91+
92+
return $iter($list, null);
93+
}
94+
95+
/**
96+
* Returns length of list
97+
* @param callable $list list
98+
* @return integer length
99+
*/
100+
function length($list)
101+
{
102+
if ($list === null || !is_callable($list)) {
103+
return 0;
104+
} else {
105+
return 1 + length(cdr($list));
106+
}
107+
}

src/Pairs.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function toString($list)
3333
$arr = [];
3434
$iter = function ($items) use (&$arr, &$iter) {
3535
if ($items != null) {
36-
$arr[] = listToString(car($items));
36+
$arr[] = toString(car($items));
3737
$iter(cdr($items));
3838
}
3939

tests/ListsTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace Pairs\tests;
4+
5+
use function Pairs\cons;
6+
use function Pairs\car;
7+
use function Pairs\cdr;
8+
use function Pairs\toString;
9+
use function Lists\length;
10+
use function Lists\reverse;
11+
use function Lists\map;
12+
use function Lists\filter;
13+
use function Lists\reduce;
14+
15+
class ListsTest extends \PHPUnit_Framework_TestCase
16+
{
17+
18+
public function testLength()
19+
{
20+
$list = cons(1, cons(2, cons(3, null)));
21+
$this->assertEquals(3, length($list));
22+
}
23+
24+
public function testReverse()
25+
{
26+
$list = cons(1, cons(2, cons(3, null)));
27+
$expected = toString(cons(3, cons(2, cons(1, null))));
28+
$this->assertEquals($expected, toString(reverse($list)));
29+
}
30+
31+
public function testMap()
32+
{
33+
$list = cons(1, cons(2, cons(3, null)));
34+
$expected = toString(cons(3, cons(4, cons(5, null))));
35+
$map = map(function ($x) {
36+
return $x + 2;
37+
}, $list);
38+
$this->assertEquals($expected, toString($map));
39+
}
40+
41+
public function testFilter()
42+
{
43+
$list = cons(2, cons(3, cons(4, null)));
44+
$expected = toString(cons(2, cons(4, null)));
45+
$filter = filter(function ($x) {
46+
return $x % 2 == 0;
47+
}, $list);
48+
49+
$this->assertEquals(2, length($filter));
50+
$this->assertEquals($expected, toString($filter));
51+
}
52+
53+
public function testReduce()
54+
{
55+
$list = cons(1, cons(2, cons(3, null)));
56+
$expected = 6;
57+
$map = reduce(function ($x, $acc) {
58+
return $x + $acc;
59+
}, $list, 0);
60+
$this->assertEquals($expected, $map);
61+
}
62+
}

0 commit comments

Comments
 (0)