Test Failed
Push — master ( 79d7ec...6a4583 )
by Jean
02:12
created

ChainableArray_NativeFunctions_Trait::keyExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
namespace JClaveau\Arrays;
3
4
/**
5
 * This Trait gathers methods corresponding to all functions prefixed
6
 * by "array_" in PHP.
7
 * The behaviour of some of them is changed to give them more flexibility.
8
 *
9
 * Only those I needed are implemented. Others can miss.
10
 *
11
 * @see http://php.net/manual/fr/ref.array.php
12
 */
13
trait ChainableArray_NativeFunctions_Trait
14
{
15
    /**
16
     * This is an enhanced version of array_column. It preserves index
17
     * keys of associative arrays.
18
     *
19
     * @param $column_names         The columns to keep
0 ignored issues
show
Bug introduced by
The type JClaveau\Arrays\The was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
     * @param $index_key (optional) The column to use as new index key.
0 ignored issues
show
Bug introduced by
The type JClaveau\Arrays\optional was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
     *                              The current key we be kept if null.
22
     * @return $this
23
     */
24
    public function columns($column_names, $index_key=null)
25
    {
26
        $out = [];
27
        foreach ($this->data as $key => &$row) {
28
29
            if ($index_key)
30
                $key = $row[$index_key];
31
32
            if (is_array($column_names)) {
33
                $out[$key] = [];
34
                foreach ($column_names as $column_name) {
35
                    if (!array_key_exists($column_name, $row)) {
36
                        self::throwUsageException(
37
                             "Trying to extract a column from a row which"
38
                            ." doesn't contain it : '$column_name' \n"
39
                            .var_export($row, true)
40
                        );
41
                    }
42
43
                    $out[$key][$column_name] = $row[$column_name];
44
                }
45
            }
46
            else {
47
                // This avoids issues with isset, array_key_exists and
48
                // null entries on objects and arrays.
49
                if ($row instanceof static) {
50
                    $keys = $row->copy()->keys();
0 ignored issues
show
Bug introduced by
It seems like copy() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

50
                    $keys = $row->/** @scrutinizer ignore-call */ copy()->keys();
Loading history...
51
                }
52
                elseif (is_array($row)) {
53
                    $keys = array_keys($row);
54
                }
55
                elseif (is_scalar($row)) {
56
                    $keys = [];
57
                }
58
                else {
59
                    // todo : handle other classes supporting ArrayAccess?
60
                    $keys = [];
61
                }
62
63
                if (!in_array($column_names, $keys)) {
64
                    self::throwUsageException('A row have no index to '
65
                        .'fill the column: '.$column_names."\n"
66
                        .$key.' => '.var_export($row, true));
67
                }
68
69
                $out[$key] = $row[$column_names];
70
            }
71
        }
72
73
        return $this->returnConstant($out);
0 ignored issues
show
Bug introduced by
It seems like returnConstant() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
        return $this->/** @scrutinizer ignore-call */ returnConstant($out);
Loading history...
74
    }
75
76
    /**
77
     * Rename of column as multiple columns can be retrieved
78
     *
79
     * @deprecated Use columns() instead
80
     */
81
    public function column($column_names, $index_key=null)
82
    {
83
        return $this->columns($column_names, $index_key);
84
    }
85
86
    /**
87
     * Equivalent of array_sum.
88
     *
89
     * @return array The sum.
90
     */
91
    public function sum()
92
    {
93
        return Arrays::sum($this->data);
0 ignored issues
show
Bug Best Practice introduced by
The expression return JClaveau\Arrays\Arrays::sum($this->data) returns the type double|integer which is incompatible with the documented return type array.
Loading history...
94
    }
95
96
    /**
97
     * Equivalent of min.
98
     *
99
     * @param  $default_value To use if the array is empty
0 ignored issues
show
Bug introduced by
The type JClaveau\Arrays\To was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
100
     * @return array The min.
101
     */
102
    public function min($default_value=null)
103
    {
104
        if ($this->isEmpty() && $default_value !== null)
0 ignored issues
show
Bug introduced by
It seems like isEmpty() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

104
        if ($this->/** @scrutinizer ignore-call */ isEmpty() && $default_value !== null)
Loading history...
105
            return $default_value;
106
107
        try {
108
            return min($this->data);
109
        }
110
        catch (\Exception $e) {
111
            $message = $e->getMessage();
112
            if ($e->getMessage() == 'min(): Array must contain at least one element')
113
                $message .= ' or you can set a default value as parameter';
114
115
            $this->throwUsageException($message);
0 ignored issues
show
Bug introduced by
It seems like throwUsageException() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
            $this->/** @scrutinizer ignore-call */ 
116
                   throwUsageException($message);
Loading history...
116
        }
117
    }
118
119
    /**
120
     * Equivalent of max.
121
     *
122
     * @param  $default_value To use if the array is empty
123
     * @return array The max.
124
     */
125
    public function max($default_value=null)
126
    {
127
        if ($this->isEmpty() && $default_value !== null)
128
            return $default_value;
129
130
        try {
131
            return max($this->data);
132
        }
133
        catch (\Exception $e) {
134
            $message = $e->getMessage();
135
            if ($e->getMessage() == 'max(): Array must contain at least one element')
136
                $message .= ' or you can set a default value as parameter';
137
138
            $this->throwUsageException($message);
139
        }
140
    }
141
142
    /**
143
     * Equivalent of count().
144
     *
145
     * @return int The number of rows.
146
     */
147
    public function count()
148
    {
149
        return count($this->data);
150
    }
151
152
    /**
153
     * Computes the average on a unidimensional array of numbers
154
     *
155
     * @return int The average
156
     */
157
    public function average()
158
    {
159
        return array_sum($this->data) / count($this->data);
160
    }
161
162
    /**
163
     * Equivalent of array_values.
164
     *
165
     * @return $this
166
     */
167
    public function values()
168
    {
169
        $out = array_values($this->data);
170
        return $this->returnConstant($out);
171
    }
172
173
    /**
174
     * Equivalent of array_filter as if used with the flag
175
     * ARRAY_FILTER_USE_BOTH.
176
     *
177
     * @param  callable|array $callback The filter logic with $value and $key
178
     *                            as parameters.
179
     *
180
     * @return static $this or a new static.
181
     */
182
    public function filter($callback=null)
183
    {
184
        if ($callback) {
185
186
            if (is_array($callback)) {
187
                $callback = new \JClaveau\LogicalFilter\LogicalFilter($callback);
0 ignored issues
show
Bug introduced by
The type JClaveau\LogicalFilter\LogicalFilter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
188
            }
189
190
            if (!is_callable($callback)) {
191
                $this->throwUsageException(
192
                    "\$callback must be a logical filter description array or a callable"
193
                    ." instead of "
194
                    .var_export($callback, true)
195
                );
196
            }
197
198
199
            // Flags are supported since 5.6
200
            if (PHP_VERSION_ID >= 50600) {
201
                $out = array_filter($this->data, $callback,
202
                    ARRAY_FILTER_USE_BOTH);
203
            }
204
            else {
205
                $out = $this->data;
206
                foreach ($out as $key => $value) {
207
                    if (!$callback($value, $key))
208
                        unset( $out[$key] );
209
                }
210
            }
211
        }
212
        else {
213
            $out = array_filter($this->data);
214
        }
215
216
        return $this->returnConstant($out);
217
    }
218
219
    /**
220
     * Equivalent of array_filter but filtering on keys
221
     *
222
     * @see self::filter()
223
     * @deprecated
224
     *
225
     * @return static $this or a new static.
226
     */
227
    public function filterKey(callable $callback=null)
0 ignored issues
show
Unused Code introduced by
The parameter $callback is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

227
    public function filterKey(/** @scrutinizer ignore-unused */ callable $callback=null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
228
    {
229
        throw new \ErrorException('This method is replaced by '
230
            . __TRAIT__ . '::filtr()');
231
    }
232
233
    /**
234
     * Remove doesn't exist but look a lot like filter so I place it here.
235
     *
236
     * @param * $item_to_remove
0 ignored issues
show
Documentation Bug introduced by
The doc comment $item_to_remove at position 0 could not be parsed: Unknown type name '$item_to_remove' at position 0 in $item_to_remove.
Loading history...
237
     *
238
     * @return static $this or a new static.
239
     */
240
    public function remove($item_to_remove)
241
    {
242
        $out = [];
243
        foreach ($this->data as $i => $data_item) {
244
245
            if ($data_item == $item_to_remove)
246
                continue;
247
248
            $out[$i] = $data_item;
249
        }
250
251
        return $this->returnConstant($out);
252
    }
253
254
    /**
255
     * Equivalent of array_intersect_key()
256
     *
257
     * @return static $this or a new static.
258
     */
259
    public function intersectKey($intersect_with)
260
    {
261
        if (!$this->argumentIsArrayOrArrayObject($intersect_with))
0 ignored issues
show
Bug introduced by
It seems like argumentIsArrayOrArrayObject() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

261
        if (!$this->/** @scrutinizer ignore-call */ argumentIsArrayOrArrayObject($intersect_with))
Loading history...
262
            self::throwUsageException("First argument must be an array or a ".static::class.".");
263
264
        if ($intersect_with instanceof static)
265
            $intersect_with = $intersect_with->getArray();
0 ignored issues
show
Bug introduced by
It seems like getArray() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

265
            /** @scrutinizer ignore-call */ 
266
            $intersect_with = $intersect_with->getArray();
Loading history...
266
267
        $out = array_intersect_key($this->data, $intersect_with);
268
269
        return $this->returnConstant($out);
270
    }
271
272
    /**
273
     * Equivalent of array_flip()
274
     *
275
     * @return static $this or a new static.
276
     */
277
    public function flip()
278
    {
279
        $out = array_flip($this->data);
280
        return $this->returnConstant($out);
281
    }
282
283
    /**
284
     * Equivalent of array_shift()
285
     *
286
     * @return The extracted first value
287
     */
288
    public function shift()
289
    {
290
        return array_shift($this->data);
291
    }
292
293
    /**
294
     * Equivalent of array_unshift()
295
     *
296
     * @return static $this.
297
     */
298
    public function unshift()
299
    {
300
        $data = $this->data;
301
        $arguments = Arrays::merge( [&$data], func_get_args() );
302
303
        call_user_func_array('array_unshift', $arguments);
304
        return $this->returnConstant($data);
305
    }
306
307
    /**
308
     * Equivalent of array_push()
309
     *
310
     * @return static $this or a new static.
311
     */
312
    public function push()
313
    {
314
        $data = $this->data;
315
        $arguments = Arrays::merge( [&$data], func_get_args() );
316
317
        call_user_func_array('array_push', $arguments);
318
        return $this->returnConstant($data);
319
    }
320
321
    /**
322
     * Equivalent of array_unique()
323
     *
324
     * @return static $this or a new static.
325
     */
326
    public function unique($flags=SORT_STRING)
327
    {
328
        $out = array_unique($this->data, $flags);
329
        return $this->returnConstant($out);
330
    }
331
332
    /**
333
     * Equivalent of array_diff() but supporting associative arrays
334
     * comparaison.
335
     *
336
     * Contrary to array_diff, only one iterable can be given as argument.
337
     *
338
     * Supports also :
339
     * + Keys comparison
340
     * + Strict comparison
341
     *
342
     * @param Iterable $compare_with      Values to compare with.
343
     * @param bool     $check_keys        Compare also keys of items before
344
     *                                    considering them equals.
345
     * @param bool     $strict_comparison Perform strict comparaisons
346
     *                                    between items and keys.
347
     *
348
     * @see http://php.net/manual/en/function.array-diff.php
349
     *
350
     * @return static $this or a new static.
351
     */
352
    public function diff($compare_with, $check_keys=false, $strict_comparison=false)
353
    {
354
        if (!$this->argumentIsArrayOrArrayObject($compare_with))
355
            self::throwUsageException("First argument must be an iterable");
356
357
        $kept_values = $this->data;
358
359
        foreach ($kept_values as $kept_key => $kept_value) {
360
            foreach ($compare_with as $compared_key => $compared_value) {
361
362
                $is_equal = false;
363
364
                if ($check_keys) {
365
366
                    if ($strict_comparison) {
367
                        if (    $kept_key   === $compared_key
368
                            &&  $kept_value === $compared_value ) {
369
                            $is_equal = true;
370
                        }
371
                    }
372
                    else {
373
                        if (    $kept_key   == $compared_key
374
                            &&  $kept_value == $compared_value ) {
375
                            $is_equal = true;
376
                        }
377
                    }
378
                }
379
                else {
380
                    if ($strict_comparison) {
381
                        if ($kept_value === $compared_value) {
382
                            $is_equal = true;
383
                        }
384
                    }
385
                    else {
386
                        if ($kept_value == $compared_value) {
387
                            $is_equal = true;
388
                        }
389
                    }
390
                }
391
392
                if ($is_equal) {
393
                    // Debug::dumpJson($kept_key, !true);
394
                    unset($kept_values[ $kept_key ]);
395
                    break;
396
                }
397
            }
398
        }
399
400
        // Debug::dumpJson($kept_values, true);
401
402
        return $this->returnConstant($kept_values);
403
    }
404
405
    /**
406
     * Equivalent of array_pop()
407
     *
408
     * @return The extracted last value
409
     */
410
    public function pop()
411
    {
412
        return array_pop($this->data);
413
    }
414
415
    /**
416
     * Equivalent of array_fill_keys.
417
     *
418
     * @see    http://php.net/manual/en/function.array-fill-keys.php
419
     *
420
     * @return static The filled array.
421
     */
422
    public function fillKeys($keys, $value)
423
    {
424
        if (!$this->argumentIsArrayOrArrayObject($keys))
425
            self::throwUsageException("First argument must be an array or a ".static::class.".");
426
427
        if ($keys instanceof static)
428
            $keys = $keys->getArray();
429
430
        $out = array_fill_keys($keys, $value);
431
        return $this->returnConstant($out);
432
    }
433
434
    /**
435
     * Equivalent of array_fill.
436
     *
437
     * @see    http://php.net/manual/en/function.array-fill.php
438
     *
439
     * @return static The filled array.
440
     */
441
    public function fill($start, $number, $value, $interval=1)
442
    {
443
        $out = [];
444
        while ($number >= 0) {
445
            $out[$start] = $value;
446
            $start += $interval;
447
            $number--;
448
        }
449
450
        return $this->returnConstant($out);
451
    }
452
453
    /**
454
     * This is a fully permissive equivalent of array_fill.
455
     *
456
     * @param  scalar    $zero_key       Your starting point reference
457
     * @param  scalar    $end_key        The last key of the resulting array
458
     * @param  callable  $step_generator The callback defining the current step
459
     *                                   based on the previous one.
460
     * @param  int       $max_interations_count A limit to avoid inifinite loops
461
     *                                   set to 1000 by default.
462
     *
463
     * @see    http://php.net/manual/en/function.array-fill.php
464
     *
465
     * @return static The filled array.
466
     */
467
    public function fillWithSeries(
468
        $zero_key,
469
        $end_key,
470
        callable $step_generator,
471
        $max_interations_count=1000
472
    ){
473
        if ($max_interations_count < 0)
474
            throw new \InvalidArgumentException("$maximum_interations_count must be positive");
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $maximum_interations_count seems to be never defined.
Loading history...
475
476
        $out                 = [];
477
        $previous_step_value = null;
478
        $current_step_key    = $zero_key;
479
        $iterations_count    = 0;
480
481
        while ($iterations_count <= $max_interations_count) {
482
            $current_step_value = call_user_func_array( $step_generator, [
483
                &$current_step_key,   // param by reference
484
                $previous_step_value,
485
                $current_step_key,   // not passed by ref
486
                $out
487
            ]);
488
489
            if ($current_step_key === null) {
490
                $out[] = $current_step_value;
491
            }
492
            elseif (!is_int($current_step_key)) {
493
                // Set the local as en_US tu have floats formatted with
494
                // "." as separator
495
                // TODO : could it be useful for dates to?
496
                $current_locale = setlocale(LC_NUMERIC, 'en_US');
497
                $out[(string) $current_step_key] = $current_step_value;
498
                setlocale(LC_NUMERIC, $current_locale);
499
            }
500
            else {
501
                $out[$current_step_key] = $current_step_value;
502
            }
503
504
            if (is_float($current_step_key) || is_float($end_key)) {
505
                // float comparison can lead complex behaviour
506
                // https://stackoverflow.com/questions/3148937/compare-floats-in-php
507
508
                if ((string) $current_step_key == (string) $end_key) {
509
                    break;
510
                }
511
            }
512
            elseif ($current_step_key == $end_key) {
513
                break;
514
            }
515
516
            $previous_step_value = $current_step_value;
517
            $iterations_count++;
518
        }
519
520
        return $this->returnConstant($out);
521
    }
522
523
    /**
524
     * Equivalent of array_keys.
525
     *
526
     * @see    http://php.net/manual/fr/function.array-keys.php
527
     *
528
     * @return array The keys.
529
     */
530
    public function keys($search_value=null, $strict=false)
531
    {
532
        if ($search_value)
533
            return array_keys($this->data, $search_value, $strict);
534
        else
535
            return array_keys($this->data);
536
    }
537
538
    /**
539
     * Equivalent of implode.
540
     * NB : "explode()" should not be implemented here but into a String
541
     *      class if you really want it.
542
     *
543
     * @see    http://php.net/manual/fr/function.implode.php
544
     *
545
     * @return string The joined values
546
     */
547
    public function implode($glue)
548
    {
549
        return implode($glue, $this->data);
550
    }
551
552
    /**
553
     * Equivalent of var_export().
554
     *
555
     * @see    http://php.net/manual/fr/function.var-export.php
556
     * @param  bool $return Should we print it or return it?
557
     *                      Its default value is the opposit of the PHP
558
     *                      one as it's more often used this way.
559
     *
560
     * @return string The array written in PHP code.
561
     */
562
    public function export($return=true)
563
    {
564
        return var_export($this->data, $return);
0 ignored issues
show
Bug introduced by
Are you sure the usage of var_export($this->data, $return) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
565
    }
566
567
    /**
568
     * Equivalent of print_r().
569
     *
570
     * @see    http://php.net/manual/fr/function.print-r.php
571
     *
572
     * @param  bool $return Should we print it or return it?
573
     * @return string The printed array
574
     */
575
    public function print_($return=false)
576
    {
577
        if (!$return) {
578
579
            echo '<pre>';
580
            print_r($this->data);
581
            echo '</pre>';
582
583
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type JClaveau\Arrays\Chainabl...y_NativeFunctions_Trait which is incompatible with the documented return type string.
Loading history...
584
        } else {
585
            return print_r($this->data, true);
586
        }
587
    }
588
589
    /**
590
     * Equivalent of key().
591
     *
592
     * @see http://php.net/manual/fr/function.key.php
593
     */
594
    public function key()
595
    {
596
        return key($this->data);
597
    }
598
599
    /**
600
     * Equivalent of current().
601
     *
602
     * @see  http://php.net/manual/fr/function.current.php
603
     * @todo Exception if the pointer is above the length?
604
     */
605
    public function current()
606
    {
607
        return current($this->data);
608
    }
609
610
    /**
611
     * Equivalent of next().
612
     *
613
     * @see http://php.net/manual/fr/function.next.php
614
     */
615
    public function next()
616
    {
617
        next($this->data);
618
        return $this;
619
    }
620
621
    /**
622
     * Equivalent of prev().
623
     *
624
     * @see http://php.net/manual/fr/function.prev.php
625
     */
626
    public function prev()
627
    {
628
        prev($this->data);
629
        return $this;
630
    }
631
632
    /**
633
     * Equivalent of uasort().
634
     *
635
     * @see http://php.net/manual/fr/function.prev.php
636
     */
637
    public function usort(callable $callback=null)
638
    {
639
        $data = $this->data;
640
641
        if ($callback === null) {
642
            $callback = function($a, $b) {
643
                if ($a == $b)
644
                    return 0;
645
646
                return $a > $b ? -1 : 1;
647
            };
648
        }
649
650
        $arguments = Arrays::merge( [&$data], [$callback] );
651
652
        if ( ! call_user_func_array('uasort', $arguments) )
653
            throw new \ErrorException('Unable to apply usort');
654
655
        return $this->returnConstant($data);
656
    }
657
658
    /**
659
     * Equivalent of uksort().
660
     *
661
     * @see http://php.net/manual/fr/function.uksort.php
662
     */
663
    public function uksort(callable $callback=null)
664
    {
665
        $data = $this->data;
666
667
        if ($callback === null) {
668
            $callback = function($a, $b) {
669
                return $a >= $b;
670
            };
671
        }
672
673
        $arguments = Arrays::merge( [&$data], [$callback] );
674
675
        if ( ! call_user_func_array('uksort', $arguments) )
676
            throw new \ErrorException('Unable to apply uksort');
677
678
        return $this->returnConstant($data);
679
    }
680
681
    /**
682
     * Equivalent of array_intersect()
683
     *
684
     * @param Array|static $intersect_with
685
     * @return static $this or a new static.
686
     */
687
    public function intersect($intersect_with)
688
    {
689
        if (!$this->argumentIsArrayOrArrayObject($intersect_with)) {
690
            $this->throwUsageException("First argument must be an array or a ".static::class.".");
691
        }
692
693
        if ($intersect_with instanceof static) {
694
            $intersect_with = $intersect_with->getArray();
695
        }
696
697
        return $this->returnConstant(array_intersect($this->data, $intersect_with));
698
    }
699
700
    /**
701
     */
702
    public function keyExists($key)
703
    {
704
        return array_key_exists($key, $this->data);
705
    }
706
707
    /**/
708
}
709