1: <?php
2: /*
3: * Copyright (c) 2014 @trashtoy
4: * https://github.com/trashtoy/
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy of
7: * this software and associated documentation files (the "Software"), to deal in
8: * the Software without restriction, including without limitation the rights to use,
9: * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10: * Software, and to permit persons to whom the Software is furnished to do so,
11: * subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in all
14: * copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18: * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19: * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20: * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21: * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22: */
23: /**
24: * PHP class file.
25: * @auhtor trashtoy
26: * @since 2.0.0
27: */
28: namespace Peach\Util;
29:
30: /**
31: * PHP の配列機能を使った Map の実装です.
32: * このマップはキーに整数または文字列しか使えないという制限があります.
33: *
34: * このクラスは foreach で各マッピングのキーと値を取り出すことが出来ます.
35: */
36: class ArrayMap implements Map, \IteratorAggregate
37: {
38: /**
39: * マッピングを保持する配列です.
40: * @var array
41: */
42: private $data;
43:
44: /**
45: * 新しいインスタンスを構築します.
46: * @param Map|array $var 指定された配列またはマッピングでこのマップを初期化します.
47: */
48: public function __construct($var = null)
49: {
50: if ($var instanceof ArrayMap) {
51: $this->data = $var->data;
52: return;
53: }
54:
55: if ($var instanceof Map) {
56: $this->data = array();
57: $entryList = $var->entryList();
58: foreach ($entryList as $entry) {
59: $this->put($entry->getKey(), $entry->getValue());
60: }
61: return;
62: }
63:
64: if (!isset($var)) {
65: $this->data = array();
66: } elseif (is_array($var)) {
67: $this->data = $var;
68: } else {
69: throw new \InvalidArgumentException("Argument (" . Values::getType($var) . ") must be array or \\Peach\\Util\\Map");
70: }
71: }
72:
73: /**
74: * 指定されたキー名にマッピングされている値を返します.
75: * マッピングが存在しない場合は代替値 (デフォルトは NULL) を返します.
76: * このメソッドの返り値が NULL (または指定した代替値) の場合, 必ずしもマッピングが存在しないとは限りません.
77: * マッピングが存在するかどうかを調べる場合は {@link ArrayMap::containsKey} を使用してください.
78: *
79: * @param string $name キー名
80: * @param mixed $defaultValue デフォルト値
81: * @return mixed 指定したキーに関連づけられた値. 存在しない場合は $defaultValue を返す
82: */
83: public function get($name, $defaultValue = null)
84: {
85: return (isset($this->data[$name])) ? $this->data[$name] : $defaultValue;
86: }
87:
88: /**
89: * 指定されたキー名と値を関連づけます.
90: * この実装では, 内部に保存されている配列に対して
91: * <code>
92: * $arr[$key] = $value;
93: * </code>
94: * を実行するのと同等の操作を行います.
95: * もしも $key に非スカラー値 (オブジェクトや配列など) が指定された場合は,
96: * {@link Values::stringValue} で string 型に変換した結果をキーとします.
97: *
98: * @param string $key キー名
99: * @param mixed $value 指定されたキーに関連づける値
100: */
101: public function put($key, $value)
102: {
103: if (!is_scalar($key)) {
104: $key = Values::stringValue($key);
105: }
106:
107: $this->data[$key] = $value;
108: }
109:
110: /**
111: * 指定された Map のマッピングをすべて登録します.
112: *
113: * @param Map $map
114: * @see Map::putAll
115: */
116: public function putAll(Map $map)
117: {
118: $entryList = $map->entryList();
119: foreach ($entryList as $entry) {
120: $this->put($entry->getKey(), $entry->getValue());
121: }
122: }
123:
124: /**
125: * 指定されたキー名によるマッピングが存在するかどうかを調べます.
126: * マッピングが存在する場合に TRUE を返します.
127: *
128: * @param string $name キー名
129: * @return bool マッピングが存在する場合に TRUE
130: */
131: public function containsKey($name)
132: {
133: return array_key_exists($name, $this->data);
134: }
135:
136: /**
137: * 指定されたキー名によるマッピングが存在する場合に, そのマッピングを削除します.
138: * @param string $key キー名
139: */
140: public function remove($key)
141: {
142: if (isset($this->data[$key])) {
143: unset($this->data[$key]);
144: }
145: }
146:
147: /**
148: * このマップを空にします.
149: */
150: public function clear()
151: {
152: $this->data = array();
153: }
154:
155: /**
156: * 登録されているマッピングの個数を返します.
157: * @return int
158: */
159: public function size()
160: {
161: return count($this->data);
162: }
163:
164: /**
165: * このマップに登録されているすべてのキーを配列で返します.
166: * 返される配列に対する操作はこのマップには反映されません.
167: *
168: * @return array
169: */
170: public function keys()
171: {
172: return array_keys($this->data);
173: }
174:
175: /**
176: * このマップに登録されているすべての値を配列で返します.
177: * 返される配列に対する操作はこのマップには反映されません.
178: * @return array
179: */
180: public function values()
181: {
182: return array_values($this->data);
183: }
184:
185: /**
186: * このマップに含まれるすべてのエントリーを返します.
187: *
188: * @return array {@link MapEntry} の配列
189: */
190: public function entryList()
191: {
192: $result = array();
193: foreach ($this->data as $key => $value) {
194: $result[] = new ArrayMapEntry($key, $value, $this);
195: }
196: return $result;
197: }
198:
199: /**
200: * このマップに登録されているエントリーを配列として返します.
201: * 返される配列に対する操作はこのマップには反映されません.
202: *
203: * @return array このマップの配列表現
204: */
205: public function asArray()
206: {
207: return $this->data;
208: }
209:
210: /**
211: * このマップに登録されているマッピングを取り出す Iterator を返します.
212: * @return \Iterator
213: */
214: public function getIterator()
215: {
216: return new \ArrayIterator($this->data);
217: }
218: }
219: