UnderscoreArray::intersection()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
cc 1
eloc 3
c 2
b 0
f 2
nc 1
nop 1
dl 0
loc 6
rs 10
1
<?php
2
3
/*
4
 * This file is part of the PHP-UNDERSCORE package.
5
 *
6
 * (c) Jitendra Adhikari <[email protected]>
7
 *     <https://github.com/adhocore>
8
 *
9
 * Licensed under MIT license.
10
 */
11
12
namespace Ahc\Underscore;
13
14
class UnderscoreArray extends UnderscoreCollection
15
{
16
    /**
17
     * Get the first n items.
18
     *
19
     * @param int $n
20
     *
21
     * @return array|mixed With n = 1 (default), it gives one item, which may not be array.
22
     */
23
    public function first($n = 1)
24
    {
25
        return $this->slice($n, true);
26
    }
27
28
    /**
29
     * Get the last n items.
30
     *
31
     * @param int $n
32
     *
33
     * @return array|mixed With n = 1 (default), it gives one item, which may not be array.
34
     */
35
    public function last($n = 1)
36
    {
37
        return $this->slice($n, false);
38
    }
39
40
    /**
41
     * Extracts n items from first or last.
42
     *
43
     * @internal
44
     *
45
     * @param int  $n
46
     * @param bool $isFirst From first if true, else last.
47
     *
48
     * @return array|mixed With n = 1 (default), it gives one item, which may not be array.
49
     */
50
    protected function slice($n, $isFirst = true)
51
    {
52
        if ($n < 2) {
53
            return $isFirst ? \reset($this->data) : \end($this->data);
54
        }
55
56
        if ($n >= $c = $this->count()) {
57
            return $this->data;
58
        }
59
60
        return \array_slice($this->data, $isFirst ? 0 : $c - $n, $isFirst ? $n : null, true);
61
    }
62
63
    /**
64
     * Get only the truthy items.
65
     *
66
     * @return self
67
     */
68
    public function compact()
69
    {
70
        return $this->filter(null);
71
    }
72
73
    /**
74
     * Gets the flattened version of multidimensional items.
75
     *
76
     * @return self
77
     */
78
    public function flatten()
79
    {
80
        return new static($this->flat($this->data));
81
    }
82
83
    /**
84
     * Gets the unique items using the id resulted from callback.
85
     *
86
     * @param callable|string $fn The callback. String is resolved to value of that index.
87
     *
88
     * @return self
89
     */
90
    public function unique($fn = null)
91
    {
92
        if (null === $fn) {
93
            return new static(\array_unique($this->data));
94
        }
95
96
        $ids = [];
97
        $fn  = $this->valueFn($fn);
98
99
        return $this->filter(function ($value, $index) use ($fn, &$ids) {
100
            return !isset($ids[$id = $fn($value, $index)]) ? $ids[$id] = true : false;
101
        });
102
    }
103
104
    /**
105
     * Get the items whose value is not in given data.
106
     *
107
     * @param array|mixed $data Array or array like or array convertible.
108
     *
109
     * @return self
110
     */
111
    public function difference($data)
112
    {
113
        $data = $this->asArray($data);
114
115
        return $this->filter(function ($value) use ($data) {
116
            return !\in_array($value, $data);
117
        });
118
    }
119
120
    /**
121
     * Get the union/merger of items with given data.
122
     *
123
     * @param array|mixed $data Array or array like or array convertible.
124
     *
125
     * @return self
126
     */
127
    public function union($data)
128
    {
129
        return new static(\array_merge($this->data, $this->asArray($data)));
130
    }
131
132
    /**
133
     * Gets the items whose value is common with given data.
134
     *
135
     * @param array|mixed $data Array or array like or array convertible.
136
     *
137
     * @return self
138
     */
139
    public function intersection($data)
140
    {
141
        $data = $this->asArray($data);
142
143
        return $this->filter(function ($value) use ($data) {
144
            return \in_array($value, $data);
145
        });
146
    }
147
148
    /**
149
     * Group the values from data and items having same indexes together.
150
     *
151
     * @param array|mixed $data Array or array like or array convertible.
152
     *
153
     * @return self
154
     */
155
    public function zip($data)
156
    {
157
        $data = $this->asArray($data);
158
159
        return $this->map(function ($value, $index) use ($data) {
160
            return [$value, isset($data[$index]) ? $data[$index] : null];
161
        });
162
    }
163
164
    /**
165
     * Hydrate the items into given class or stdClass.
166
     *
167
     * @param string|null $className FQCN of the class whose constructor accepts two parameters: value and index.
168
     *
169
     * @return self
170
     */
171
    public function object($className = null)
172
    {
173
        return $this->map(function ($value, $index) use ($className) {
174
            return $className ? new $className($value, $index) : (object) \compact('value', 'index');
175
        });
176
    }
177
178
    /**
179
     * Find the first index that passes given truth test.
180
     *
181
     * @param callable $fn The truth test callback.
182
     *
183
     * @return mixed|null
184
     */
185
    public function findIndex($fn = null)
186
    {
187
        return $this->find($this->valueFn($fn), false);
188
    }
189
190
    /**
191
     * Find the last index that passes given truth test.
192
     *
193
     * @param callable $fn The truth test callback.
194
     *
195
     * @return mixed|null
196
     */
197
    public function findLastIndex($fn = null)
198
    {
199
        return (new static(\array_reverse($this->data, true)))->find($this->valueFn($fn), false);
200
    }
201
202
    /**
203
     * Find the first index of given value if available null otherwise.
204
     *
205
     * @param mixed $value The lookup value.
206
     *
207
     * @return string|int|null
208
     */
209
    public function indexOf($value)
210
    {
211
        return (false === $index = \array_search($value, $this->data)) ? null : $index;
212
    }
213
214
    /**
215
     * Find the last index of given value if available null otherwise.
216
     *
217
     * @param mixed $value The lookup value.
218
     *
219
     * @return string|int|null
220
     */
221
    public function lastIndexOf($value)
222
    {
223
        return (false === $index = \array_search($value, \array_reverse($this->data, true))) ? null : $index;
224
    }
225
226
    /**
227
     * Gets the smallest index at which an object should be inserted so as to maintain order.
228
     *
229
     * Note that the initial stack must be sorted already.
230
     *
231
     * @param mixed           $object The new object which needs to be adjusted in stack.
232
     * @param callable|string $fn     The comparator callback.
233
     *
234
     * @return string|int|null
235
     */
236
    public function sortedIndex($object, $fn)
237
    {
238
        $low   = 0;
239
        $high  = $this->count();
240
        $data  = $this->values();
241
        $fn    = $this->valueFn($fn);
242
        $value = $fn($object);
243
        $keys  = $this->keys();
244
245
        while ($low < $high) {
246
            $mid = \intval(($low + $high) / 2);
247
            if ($fn($data[$mid]) < $value) {
248
                $low = $mid + 1;
249
            } else {
250
                $high = $mid;
251
            }
252
        }
253
254
        return isset($keys[$low]) ? $keys[$low] : null;
255
    }
256
257
    /**
258
     * Creates a new range from start to stop with given step.
259
     *
260
     * @param int $start
261
     * @param int $stop
262
     * @param int $step
263
     *
264
     * @return self
265
     */
266
    public function range($start, $stop, $step = 1)
267
    {
268
        return new static(\range($start, $stop, $step));
269
    }
270
}
271