Skip to content
This repository
Browse code

Move merge() into Set2.

  • Loading branch information...
commit e736ea3af98bb4b6f0f33f6b30567f1d3af48d0f 1 parent 51f45c0
Mark Story authored January 15, 2012
171  lib/Cake/Test/Case/Utility/Set2Test.php
@@ -276,4 +276,175 @@ public function testFlatten() {
276 276
 		$this->assertEquals($expected, $result);
277 277
 	}
278 278
 
  279
+/**
  280
+ * Test diff();
  281
+ *
  282
+ * @return void
  283
+ */
  284
+	public function testDiff() {
  285
+		$a = array(
  286
+			0 => array('name' => 'main'),
  287
+			1 => array('name' => 'about')
  288
+		);
  289
+		$b = array(
  290
+			0 => array('name' => 'main'),
  291
+			1 => array('name' => 'about'),
  292
+			2 => array('name' => 'contact')
  293
+		);
  294
+
  295
+		$result = Set2::diff($a, array());
  296
+		$expected = $a;
  297
+		$this->assertEquals($expected, $result);
  298
+
  299
+		$result = Set2::diff(array(), $b);
  300
+		$expected = $b;
  301
+		$this->assertEquals($expected, $result);
  302
+
  303
+		$result = Set2::diff($a, $b);
  304
+		$expected = array(
  305
+			2 => array('name' => 'contact')
  306
+		);
  307
+		$this->assertEquals($expected, $result);
  308
+
  309
+
  310
+		$b = array(
  311
+			0 => array('name' => 'me'),
  312
+			1 => array('name' => 'about')
  313
+		);
  314
+
  315
+		$result = Set2::diff($a, $b);
  316
+		$expected = array(
  317
+			0 => array('name' => 'main')
  318
+		);
  319
+		$this->assertEquals($expected, $result);
  320
+
  321
+		$a = array();
  322
+		$b = array('name' => 'bob', 'address' => 'home');
  323
+		$result = Set2::diff($a, $b);
  324
+		$this->assertEquals($result, $b);
  325
+
  326
+
  327
+		$a = array('name' => 'bob', 'address' => 'home');
  328
+		$b = array();
  329
+		$result = Set2::diff($a, $b);
  330
+		$this->assertEquals($result, $a);
  331
+
  332
+		$a = array('key' => true, 'another' => false, 'name' => 'me');
  333
+		$b = array('key' => 1, 'another' => 0);
  334
+		$expected = array('name' => 'me');
  335
+		$result = Set2::diff($a, $b);
  336
+		$this->assertEquals($expected, $result);
  337
+
  338
+		$a = array('key' => 'value', 'another' => null, 'name' => 'me');
  339
+		$b = array('key' => 'differentValue', 'another' => null);
  340
+		$expected = array('key' => 'value', 'name' => 'me');
  341
+		$result = Set2::diff($a, $b);
  342
+		$this->assertEquals($expected, $result);
  343
+
  344
+		$a = array('key' => 'value', 'another' => null, 'name' => 'me');
  345
+		$b = array('key' => 'differentValue', 'another' => 'value');
  346
+		$expected = array('key' => 'value', 'another' => null, 'name' => 'me');
  347
+		$result = Set2::diff($a, $b);
  348
+		$this->assertEquals($expected, $result);
  349
+
  350
+		$a = array('key' => 'value', 'another' => null, 'name' => 'me');
  351
+		$b = array('key' => 'differentValue', 'another' => 'value');
  352
+		$expected = array('key' => 'differentValue', 'another' => 'value', 'name' => 'me');
  353
+		$result = Set2::diff($b, $a);
  354
+		$this->assertEquals($expected, $result);
  355
+
  356
+		$a = array('key' => 'value', 'another' => null, 'name' => 'me');
  357
+		$b = array(0 => 'differentValue', 1 => 'value');
  358
+		$expected = $a + $b;
  359
+		$result = Set2::diff($a, $b);
  360
+		$this->assertEquals($expected, $result);
  361
+	}
  362
+
  363
+/**
  364
+ * Test merge()
  365
+ *
  366
+ * @return void
  367
+ */
  368
+	public function testMerge() {
  369
+		$result = Set2::merge(array('foo'), array('bar'));
  370
+		$this->assertEquals($result, array('foo', 'bar'));
  371
+
  372
+		$result = Set2::merge(array('foo'), array('user' => 'bob', 'no-bar'), 'bar');
  373
+		$this->assertEquals($result, array('foo', 'user' => 'bob', 'no-bar', 'bar'));
  374
+
  375
+		$a = array('foo', 'foo2');
  376
+		$b = array('bar', 'bar2');
  377
+		$expected = array('foo', 'foo2', 'bar', 'bar2');
  378
+		$this->assertEquals($expected, Set2::merge($a, $b));
  379
+
  380
+		$a = array('foo' => 'bar', 'bar' => 'foo');
  381
+		$b = array('foo' => 'no-bar', 'bar' => 'no-foo');
  382
+		$expected = array('foo' => 'no-bar', 'bar' => 'no-foo');
  383
+		$this->assertEquals($expected, Set2::merge($a, $b));
  384
+
  385
+		$a = array('users' => array('bob', 'jim'));
  386
+		$b = array('users' => array('lisa', 'tina'));
  387
+		$expected = array('users' => array('bob', 'jim', 'lisa', 'tina'));
  388
+		$this->assertEquals($expected, Set2::merge($a, $b));
  389
+
  390
+		$a = array('users' => array('jim', 'bob'));
  391
+		$b = array('users' => 'none');
  392
+		$expected = array('users' => 'none');
  393
+		$this->assertEquals($expected, Set2::merge($a, $b));
  394
+
  395
+		$a = array('users' => array('lisa' => array('id' => 5, 'pw' => 'secret')), 'cakephp');
  396
+		$b = array('users' => array('lisa' => array('pw' => 'new-pass', 'age' => 23)), 'ice-cream');
  397
+		$expected = array(
  398
+			'users' => array('lisa' => array('id' => 5, 'pw' => 'new-pass', 'age' => 23)),
  399
+			'cakephp',
  400
+			'ice-cream'
  401
+		);
  402
+		$result = Set2::merge($a, $b); 
  403
+		$this->assertEquals($expected, $result);
  404
+
  405
+		$c = array(
  406
+			'users' => array('lisa' => array('pw' => 'you-will-never-guess', 'age' => 25, 'pet' => 'dog')),
  407
+			'chocolate'
  408
+		);
  409
+		$expected = array(
  410
+			'users' => array('lisa' => array('id' => 5, 'pw' => 'you-will-never-guess', 'age' => 25, 'pet' => 'dog')),
  411
+			'cakephp',
  412
+			'ice-cream',
  413
+			'chocolate'
  414
+		);
  415
+		$this->assertEquals($expected, Set2::merge($a, $b, $c));
  416
+
  417
+		$this->assertEquals($expected, Set2::merge($a, $b, array(), $c));
  418
+
  419
+		$a = array(
  420
+			'Tree',
  421
+			'CounterCache',
  422
+			'Upload' => array(
  423
+				'folder' => 'products',
  424
+				'fields' => array('image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id')
  425
+			)
  426
+		);
  427
+		$b =  array(
  428
+			'Cacheable' => array('enabled' => false),
  429
+			'Limit',
  430
+			'Bindable',
  431
+			'Validator',
  432
+			'Transactional'
  433
+		);
  434
+		$expected = array(
  435
+			'Tree',
  436
+			'CounterCache',
  437
+			'Upload' => array(
  438
+				'folder' => 'products',
  439
+				'fields' => array('image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id')
  440
+			),
  441
+			'Cacheable' => array('enabled' => false),
  442
+			'Limit',
  443
+			'Bindable',
  444
+			'Validator',
  445
+			'Transactional'
  446
+		);
  447
+		$this->assertEquals(Set2::merge($a, $b), $expected);
  448
+	}
  449
+
279 450
 }
59  lib/Cake/Utility/Set2.php
@@ -85,7 +85,7 @@ public static function filter(array $data) {
85 85
 /**
86 86
  * Collapses a multi-dimensional array into a single dimension, using a delimited array path for
87 87
  * each array element's key, i.e. array(array('Foo' => array('Bar' => 'Far'))) becomes
88  
- * array('0.Foo.Bar' => 'Far').
  88
+ * array('0.Foo.Bar' => 'Far').)
89 89
  *
90 90
  * @param array $data Array to flatten
91 91
  * @param string $separator String used to separate array key elements in a path, defaults to '.'
@@ -120,8 +120,36 @@ public static function flatten(array $data, $separator = '.') {
120 120
 		return $result;
121 121
 	}
122 122
 
  123
+/**
  124
+ * This function can be thought of as a hybrid between PHP's `array_merge` and `array_merge_recursive`.
  125
+ *
  126
+ * The difference between this method and the built-in ones, is that if an array key contains another array, then 
  127
+ * Set2::merge() will behave in a recursive fashion (unlike `array_merge`).  But it will not act recursively for
  128
+ * keys that contain scalar values (unlike `array_merge_recursive`).
  129
+ *
  130
+ * Note: This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays.
  131
+ *
  132
+ * @param array $data Array to be merged
  133
+ * @param mixed $merge Array to merge with. The argument and all trailing arguments will be array cast when merged
  134
+ * @return array Merged array
  135
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::merge
  136
+ */
123 137
 	public static function merge(array $data, $merge) {
124  
-
  138
+		$args = func_get_args();
  139
+		$return = current($args);
  140
+
  141
+		while (($arg = next($args)) !== false) {
  142
+			foreach ((array)$arg as $key => $val)	 {
  143
+				if (!empty($return[$key]) && is_array($return[$key]) && is_array($val)) {
  144
+					$return[$key] = self::merge($return[$key], $val);
  145
+				} elseif (is_int($key)) {
  146
+					$return[] = $val;
  147
+				} else {
  148
+					$return[$key] = $val;
  149
+				}
  150
+			}
  151
+		}
  152
+		return $return;
125 153
 	}
126 154
 
127 155
 /**
@@ -183,8 +211,33 @@ public static function sort(array $data, $path, $dir) {
183 211
 
184 212
 	}
185 213
 
  214
+/**
  215
+ * Computes the difference between two complex arrays.
  216
+ * This method differs from the built-in array_diff() in that it will preserve keys
  217
+ * and work on multi-dimensional arrays.
  218
+ *
  219
+ * @param mixed $data First value
  220
+ * @param mixed $data2 Second value
  221
+ * @return array Returns the key => value pairs that are not common in $data and $data2
  222
+ *    The expression for this function is ($data - $data2) + ($data2 - ($data - $data2))
  223
+ * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::diff
  224
+ */
186 225
 	public static function diff(array $data, $data2) {
187  
-
  226
+		if (empty($data)) {
  227
+			return (array)$data2;
  228
+		}
  229
+		if (empty($data2)) {
  230
+			return (array)$data;
  231
+		}
  232
+		$intersection = array_intersect_key($data, $data2);
  233
+		while (($key = key($intersection)) !== null) {
  234
+			if ($data[$key] == $data2[$key]) {
  235
+				unset($data[$key]);
  236
+				unset($data2[$key]);
  237
+			}
  238
+			next($intersection);
  239
+		}
  240
+		return $data + $data2;
188 241
 	}
189 242
 
190 243
 	public static function normalize(array $data, $assoc = true) {

0 notes on commit e736ea3

Please sign in to comment.
Something went wrong with that request. Please try again.