SortedMappedLinkedList::delete()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Smoren\Containers\Structs;
4
5
use Closure;
6
use Countable;
7
use Exception;
8
use IteratorAggregate;
9
use Smoren\Containers\Exceptions\LinkedListException;
10
use Smoren\Containers\Exceptions\MappedCollectionException;
11
use Smoren\Containers\Exceptions\MappedLinkedListException;
12
use Smoren\Containers\Exceptions\SortedLinkedListException;
13
14
/**
15
 * Class SortedMappedLinkedList
16
 */
17
class SortedMappedLinkedList implements IteratorAggregate, Countable
18
{
19
    /**
20
     * @var MappedLinkedList data source
21
     */
22
    protected MappedLinkedList $list;
23
    /**
24
     * @var Closure comparator
25
     */
26
    protected Closure $comparator;
27
28
    /**
29
     * SortedLinkedList constructor.
30
     * @param array|MappedLinkedList $input default data list
31
     * @throws Exception
32
     */
33
    public function __construct($input = [])
34
    {
35
        if($input instanceof MappedLinkedList) {
36
            $this->list = $input;
37
        } elseif(is_array($input)) {
0 ignored issues
show
introduced by
The condition is_array($input) is always true.
Loading history...
38
            $this->list = new MappedLinkedList($input);
39
        } else {
40
            $linkedListType = MappedLinkedList::class;
41
            $givenType = get_class($input);
42
            throw new SortedLinkedListException(
43
                "input must be instance of array or $linkedListType, given {$givenType}",
44
                SortedLinkedListException::STATUS_BAD_LINKED_LIST_TYPE
45
            );
46
        }
47
48
        $this->comparator = $this->getComparator();
49
        $this->refresh();
50
    }
51
52
    /**
53
     * Inserts element into collection
54
     * @param string $id element ID
55
     * @param mixed $data element data value
56
     * @return LinkedListItem
57
     * @throws MappedLinkedListException|MappedCollectionException
58
     */
59
    public function insert(string $id, $data): LinkedListItem
60
    {
61
        return $this->list->pushAfter($this->findLeftPosition($id, $data), $id, $data);
62
    }
63
64
    /**
65
     * Converts collection to array
66
     * @return array
67
     */
68
    public function toArray(): array
69
    {
70
        return $this->list->toArray();
71
    }
72
73
    /**
74
     * @inheritDoc
75
     */
76
    public function count(): int
77
    {
78
        return $this->list->count();
79
    }
80
81
    /**
82
     * @inheritDoc
83
     * @return MappedLinkedListIterator
84
     */
85
    public function getIterator(): MappedLinkedListIterator
86
    {
87
        return $this->list->getIterator();
88
    }
89
90
    /**
91
     * Returns source list
92
     * @return MappedLinkedList
93
     */
94
    public function getList(): MappedLinkedList
95
    {
96
        return $this->list;
97
    }
98
99
    /**
100
     * Removes element from the front of list
101
     * @return array [id, value]
102
     * @throws MappedLinkedListException|MappedCollectionException|LinkedListException
103
     */
104
    public function popFront(): array
105
    {
106
        return $this->list->popFront();
107
    }
108
109
    /**
110
     * Removes element from the back of list
111
     * @return array [id, value]
112
     * @throws MappedLinkedListException|MappedCollectionException|LinkedListException
113
     */
114
    public function popBack(): array
115
    {
116
        return $this->list->popBack();
117
    }
118
119
    /**
120
     * Removes element from target element position
121
     * @param string $id target element ID
122
     * @return LinkedListItem old position of element
123
     * @throws MappedLinkedListException|MappedCollectionException
124
     */
125
    public function delete(string $id): LinkedListItem
126
    {
127
        return $this->list->delete($id);
128
    }
129
130
    /**
131
     * Returns element with target element ID
132
     * @param string $id target element ID
133
     * @return mixed element data value
134
     * @throws MappedLinkedListException|MappedCollectionException
135
     */
136
    public function get(string $id)
137
    {
138
        return $this->list->get($id);
139
    }
140
141
    /**
142
     * Returns bool flag of element existence
143
     * @param string $id element ID
144
     * @return bool
145
     */
146
    public function exist(string $id): bool
147
    {
148
        return $this->list->exist($id);
149
    }
150
151
    /**
152
     * Returns element position from target element position
153
     * @param string $id target element ID
154
     * @return LinkedListItem position of element
155
     * @throws MappedLinkedListException|MappedCollectionException
156
     */
157
    public function getPosition(string $id): LinkedListItem
158
    {
159
        return $this->list->getPosition($id);
160
    }
161
162
    /**
163
     * Clears list
164
     * @return $this
165
     */
166
    public function clear(): self
167
    {
168
        $this->list->clear();
169
        return $this;
170
    }
171
172
    /**
173
     * Refreshes items order
174
     * @return $this
175
     * @throws Exception
176
     */
177
    public function refresh(): self
178
    {
179
        $this->list->sort($this->comparator);
180
        return $this;
181
    }
182
183
    /**
184
     * Returns comparator function for sorting and position search
185
     * @return callable
186
     */
187
    protected function getComparator(): callable
188
    {
189
        return function($lhs, $rhs, LinkedListItem $lhsPos, LinkedListItem $rhsPos) {
190
            return $lhsPos->getExtra() > $rhsPos->getExtra();
191
        };
192
    }
193
194
    /**
195
     * Returns position max element which is less than argument (using comparator)
196
     * @param string $id element ID
197
     * @param mixed $data element data value
198
     * @return string|null
199
     * @throws MappedLinkedListException|MappedCollectionException
200
     */
201
    protected function findLeftPosition(string $id, $data): ?string
202
    {
203
        $position = null;
204
        $possiblePosition = new LinkedListItem($data, null, null, $id);
205
        foreach($this->list as $id => $val) {
206
            if(!($this->comparator)($data, $val, $possiblePosition, $this->getPosition($id))) {
207
                break;
208
            }
209
            $position = $id;
210
        }
211
212
        return $position;
213
    }
214
215
    /**
216
     * Clones object
217
     */
218
    public function __clone()
219
    {
220
        $this->list = clone $this->list;
221
    }
222
}
223