Completed
Push — master ( a92ee2...268555 )
by Dmitry
04:05
created

Map::add()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PHPKitchen\Platform\Struct;
4
5
use PHPKitchen\Platform\Contract;
6
use PHPKitchen\Platform\Exception\Runtime\Method\InvalidArgumentException;
7
use PHPKitchen\Platform\Mixin\Properties;
8
9
/**
10
 * Represents implementation of array-based map.
11
 *
12
 * @author Dmitry Kolodko <[email protected]>
13
 * @since 1.0
14
 */
15
class Map implements Contract\Struct\Map, Contract\Data\ValueObject {
16
    use Mixin\StructureOfElementsMethods;
17
    use Mixin\CountableMethods;
18
    use Mixin\IteratorMethods;
19
    use Mixin\JsonSerializableMethods;
20
    use Properties;
21
    protected const INVALID_KEY_ERROR_MESSAGE = 'Map support only `string` keys.';
22
23
    public function __construct($elements = []) {
24
        foreach ($elements as $key => $item) {
25
            if (is_numeric($key) || !is_string($key)) {
26
                throw InvalidArgumentException::withMessage(self::INVALID_KEY_ERROR_MESSAGE);
27
            }
28
        }
29
        $this->elements = $elements;
30
    }
31
32
    /**
33
     * Named constructor.
34
     *
35
     * @param array|iterable $elements elements of collection.
36
     *
37
     * @return Map new map of specified elements.
38
     *
39
     * @since 1.0
40
     */
41
    public static function of($elements): Contract\Struct\Map {
42
        return new static($elements);
43
    }
44
45
    public function add(string $key, $element): void {
46
        $this->elements[$key] = $element;
47
    }
48
49
    public function get(string $key) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
50
        return $this->hasKey($key) ? $this->elements[$key] : null;
51
    }
52
53
    public function keysToLowerCase(): void {
54
        $this->elements = array_change_key_case($this->elements, CASE_LOWER);
55
    }
56
57
    public function keysToUpperCase(): void {
58
        $this->elements = array_change_key_case($this->elements, CASE_UPPER);
59
    }
60
61
    /**
62
     * Split collection into chunks of specified size.
63
     *
64
     * @param int $size size of each chunk.
65
     *
66
     * @return Collection a multidimensional numerically indexed collection, starting with zero,
67
     * with each dimension containing Map of specified size.
68
     *
69
     * @since 1.0
70
     */
71
    public function chunkBy(int $size): Contract\Struct\Collection {
72
        $chunks = array_chunk($this->elements, $size, $keepKeys = true);
73
        $collections = Collection::of([]);
74
        foreach ($chunks as $chunk) {
75
            $collections->add(static::of($chunk));
76
        }
77
78
        return $collections;
79
    }
80
81
    public function getKeys(): Contract\Struct\Collection {
82
        return Collection::of(array_keys($this->elements));
83
    }
84
85
    public function getValues(): Contract\Struct\Collection {
86
        return Collection::of(array_values($this->elements));
87
    }
88
89
    // region ----------------- ARRAY ACCESS METHODS -----------------
90
91
    /**
92
     * Whether a offset exists
93
     *
94
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
95
     *
96
     * @param mixed $offset <p>
97
     * An offset to check for.
98
     * </p>
99
     *
100
     * @return boolean true on success or false on failure.
101
     * </p>
102
     * <p>
103
     * The return value will be casted to boolean if non-boolean was returned.
104
     * @since 1.0
105
     */
106
    public function offsetExists($offset) {
107
        return $this->hasKey($offset);
108
    }
109
110
    /**
111
     * Offset to retrieve
112
     *
113
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
114
     *
115
     * @param mixed $offset <p>
116
     * The offset to retrieve.
117
     * </p>
118
     *
119
     * @return mixed Can return all value types.
120
     * @since 1.0
121
     */
122
    public function offsetGet($offset) {
123
        return $this->elements[$offset] ?? null;
124
    }
125
126
    /**
127
     * Offset to set
128
     *
129
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
130
     *
131
     * @param mixed $offset <p>
132
     * The offset to assign the value to.
133
     * </p>
134
     * @param mixed $value <p>
135
     * The value to set.
136
     * </p>
137
     *
138
     * @return void
139
     * @since 1.0
140
     */
141
    public function offsetSet($offset, $value) {
142
        if (!is_string($offset)) {
143
            throw InvalidArgumentException::withMessage(self::INVALID_KEY_ERROR_MESSAGE);
144
        }
145
        $this->elements[$offset] = $value;
146
    }
147
148
    /**
149
     * Offset to unset
150
     *
151
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
152
     *
153
     * @param mixed $offset <p>
154
     * The offset to unset.
155
     * </p>
156
     *
157
     * @return void
158
     * @since 1.0
159
     */
160
    public function offsetUnset($offset) {
161
        unset($this->elements[$offset]);
162
    }
163
    /// endregion
164
}