Passed
Pull Request — master (#62)
by Sergei
14:50
created

ReplaceValue::withKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Arrays\Collection\Modifier;
6
7
use Yiisoft\Arrays\Collection\Modifier\ModifierInterface\AfterMergeModifierInterface;
8
use Yiisoft\Arrays\Collection\Modifier\ModifierInterface\BeforeMergeModifierInterface;
9
10
/**
11
 * Modifier "Replace Value".
12
 *
13
 * Работает только при объединении.
14
 *
15
 * Модификатор позволяет указать элемент массива из текущей коллекции, который
16
 * будет особенным образом обработан при объединении.
17
 *
18
 * - Если в предыдущих массивах есть элементы с таким же ключом, то они будут заменены значением
19
 *   из текущего массива без объединения.
20
 *
21
 * - Если в последующих массивах есть элементы с таким же ключом, то они заменят значение из
22
 *   текущего массива без объединения.
23
 *
24
 * Если в текущем коллекции нет элемента массива с заданным ключом, то модификатор ничего не изменит.
25
 */
26
final class ReplaceValue implements BeforeMergeModifierInterface, AfterMergeModifierInterface
27
{
28
    /**
29
     * @var int|string
30
     */
31
    private $key;
32
33
    /**
34
     * @var mixed
35
     */
36
    private $value;
37
38
    private bool $setValueAfterMerge = false;
39
40
    /**
41
     * @param int|string $key
42
     */
43
    public function __construct($key)
44
    {
45
        $this->key = $key;
46
    }
47
48
    /**
49
     * @param int|string $key
50
     * @return self
51
     */
52
    public function withKey($key): self
53
    {
54
        $new = clone $this;
55
        $new->key = $key;
56
        return $new;
57
    }
58
59
    public function beforeMerge(array $arrays, int $index): array
60
    {
61
        $currentArray = $arrays[$index];
62
63
        if (!array_key_exists($this->key, $currentArray)) {
64
            return $arrays[$index];
65
        }
66
67
        foreach (array_slice($arrays, $index + 1) as $array) {
68
            if (array_key_exists($this->key, $array)) {
69
                $currentArray[$this->key] = null;
70
                return $currentArray;
71
            }
72
        }
73
74
        foreach (array_slice($arrays, 0, $index) as $array) {
75
            if (array_key_exists($this->key, $array)) {
76
                $this->value = $currentArray[$this->key];
77
                $this->setValueAfterMerge = true;
78
                return $currentArray;
79
            }
80
        }
81
82
        return $currentArray;
83
    }
84
85
    public function afterMerge(array $data): array
86
    {
87
        if ($this->setValueAfterMerge) {
88
            $data[$this->key] = $this->value;
89
            $this->setValueAfterMerge = false;
90
        }
91
        return $data;
92
    }
93
}
94