Passed
Push — master ( 8ffc57...fdc7ac )
by
unknown
03:42
created

filters.php ➔ match()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 2
dl 0
loc 11
ccs 5
cts 5
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Boudewijn Schoon <[email protected]>
4
 * @copyright Zicht Online <http://zicht.nl>
5
 */
6
7
namespace Zicht\Itertools\filters;
8
9
use Zicht\Itertools\conversions;
10
use Zicht\Itertools;
11
12
/**
13
 * Returns a filter closure that only accepts values that are instances of $CLASS.
14
 *
15
 * For example, the following will return a list where all items
16
 * are instances of class Bar:
17
 * > $list = iterable([new Foo(), new Bar(), new Moo()]);
18
 * > $result = $list->filter(type(Bar::class));
19
 * > // {1: Bar}
20
 *
21
 * For example, the following will return a list where all items
22
 * have a property or array index 'key' that is an instance
23
 * of class Foo:
24
 * > $list = iterable([['key' => new Foo()], ['key => new Bar()], ['key' => new Moo()]]);
25
 * > $result = $list->filter(type(Bar::class, 'key'));
26
 * > // {1: ['key' => Bar]}
27
 *
28
 * @param string $class
29
 * @param null|string|\Closure $strategy
30
 * @return \Closure
31
 */
32
function type($class, $strategy = null)
33
{
34 4
    $strategy = conversions\mixed_to_value_getter($strategy);
35
    return function ($value, $key = null) use ($class, $strategy) {
36 3
        return $strategy($value, $key) instanceof $class;
37 4
    };
38
}
39
40
/**
41
 * Returns a filter closure that only accepts values that are in $HAYSTACK.
42
 *
43
 * For example, the following will return a list where all items
44
 * are either 'b' or 'c':
45
 * > $list = iterable(['a', 'b', 'c', 'd', 'e']);
46
 * > $result = $list->filter(in(['b', 'c']));
47
 * > // {1: 'b', 2: 'c'}
48
 *
49
 * For example, the following will return a list where all items
50
 * have a property or array index 'key' that is either 'b' or 'c':
51
 * > $list = iterable([['key' => 'a'], ['key' => 'b'], ['key' => 'c'], ['key' => 'd'], ['key' => 'e']]);
52
 * > $result = $list->filter(in(['b', 'c'], 'key'));
53
 * > // {1: ['key' => 'b'], 2: ['key' => 'c']}
54
 *
55
 * @param null|array|string|\Iterator $haystack
56
 * @param null|string|\Closure $strategy
57
 * @param boolean $strict
58
 * @return \Closure
59
 */
60 View Code Duplication
function in($haystack, $strategy = null, $strict = false)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
61
{
62 14
    if (!is_bool($strict)) {
63 5
        throw new \InvalidArgumentException('$STRICT must be a boolean');
64
    }
65 9
    if (!is_array($haystack)) {
66 5
        $haystack = Itertools\iterable($haystack)->values();
0 ignored issues
show
Bug introduced by
It seems like $haystack can also be of type null; however, Zicht\Itertools\iterable() does only seem to accept array|string|object<Iterator>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
67
    }
68 6
    $strategy = conversions\mixed_to_value_getter($strategy);
69
    return function ($value, $key = null) use ($haystack, $strategy, $strict) {
70 6
        return in_array($strategy($value, $key), $haystack, $strict);
71 6
    };
72
}
73
74
/**
75
 * Returns a filter closure that only accepts values that are not in $HAYSTACK.
76
 *
77
 * @param array|string|\Iterator $haystack
78
 * @param null|string|\Closure $strategy
79
 * @param boolean $strict
80
 * @return \Closure
81
 *
82
 * @deprecated Instead use not(in(...))
83
 */
84 View Code Duplication
function not_in($haystack, $strategy = null, $strict = false)
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
85
{
86
    if (!is_bool($strict)) {
87
        throw new \InvalidArgumentException('$STRICT must be a boolean');
88
    }
89
    if (!is_array($haystack)) {
90
        $haystack = Itertools\iterable($haystack)->values();
91
    }
92
    $strategy = conversions\mixed_to_value_getter($strategy);
93
    return function ($value, $key = null) use ($haystack, $strategy, $strict) {
94
        return !in_array($strategy($value, $key), $haystack, $strict);
95
    };
96
}
97
98
/**
99
 * Returns a filter closure that only accepts values that are equal to $EXPECTED
100
 *
101
 * For example, the following will return a list where all items
102
 * equal 'bar':
103
 * > $list = iterable(['foo', 'bar']);
104
 * > $result = $list->filter(equals('bar'));
105
 * > // {1: 'bar'}
106
 *
107
 * For example, the following will return a list where all items
108
 * have a property or array index 'foo' that equals 'bar':
109
 * > $list = iterable([['key' => 'foo'], ['key' => 'bar']]);
110
 * > $result = $list->filter(equals('bar', 'key'));
111
 * > // {1: ['key' => 'bar']}
112
 *
113
 * @param mixed $expected
114
 * @param null|string|\Closure $strategy
115
 * @param boolean $strict
116
 * @return \Closure
117
 */
118
function equals($expected, $strategy = null, $strict = false)
119
{
120 11
    if (!is_bool($strict)) {
121 5
        throw new \InvalidArgumentException('$STRICT must be a boolean');
122
    }
123 6
    $strategy = conversions\mixed_to_value_getter($strategy);
124 6
    if ($strict) {
125
        return function ($value, $key = null) use ($expected, $strategy) {
126 1
            return $expected === $strategy($value, $key);
127 1
        };
128
    } else {
129
        return function ($value, $key = null) use ($expected, $strategy) {
130 6
            return $expected == $strategy($value, $key);
131 6
        };
132
    }
133
}
134
135
/**
136
 * Returns a filter closure that inverts the value
137
 *
138
 * For example, the following will return a list where none
139
 * of the items equal 'bar'
140
 * > $list = iterable(['foo', 'bar']);
141
 * > $result = $list->filter(not(equals('bar')));
142
 * > // {0: 'foo'}
143
 *
144
 * @param null|string|\Closure $strategy
145
 * @return \Closure
146
 */
147
function not($strategy = null)
148
{
149 2
    $strategy = conversions\mixed_to_value_getter($strategy);
150
    return function ($value, $key = null) use ($strategy) {
151 2
        return !($strategy($value, $key));
152 2
    };
153
}
154
155
/**
156
 * Returns a filter closure that only accepts values that match the given regular expression.
157
 *
158
 * For example, the following will return a list where all items
159
 * match 'bar':
160
 * > $list = iterable(['-= foo =-', '-= bar =-']);
161
 * > $result = $list->filter(match('/bar/i'));
162
 * > // {1: '-= bar =-'}
163
 *
164
 * @param string $pattern
165
 * @param null|string|\Closure $strategy
166
 * @return \Closure
167
 */
168
function match($pattern, $strategy = null)
169
{
170 7
    if (!is_string($pattern)) {
171 4
        throw new \InvalidArgumentException('$PATTERN must be a string');
172
    }
173
174 3
    $strategy = conversions\mixed_to_value_getter($strategy);
175
    return function ($value, $key = null) use ($pattern, $strategy) {
176 3
        return (bool)preg_match($pattern, $strategy($value, $key));
177 3
    };
178
}
179