Skip to content

Commit bea50fb

Browse files
committed
Keep original array order if possible when rearranging
1 parent 53c412a commit bea50fb

File tree

1 file changed

+44
-28
lines changed

1 file changed

+44
-28
lines changed

src/JsonDiff.php

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,11 @@ private function process($original, $new)
392392
return is_array($new) ? $newOrdered : (object)$newOrdered;
393393
}
394394

395+
/**
396+
* @param array $original
397+
* @param array $new
398+
* @return array
399+
*/
395400
private function rearrangeArray(array $original, array $new)
396401
{
397402
$first = reset($original);
@@ -412,7 +417,7 @@ private function rearrangeArray(array $original, array $new)
412417

413418
$keyIsUnique = true;
414419
$uniqueIdx = array();
415-
foreach ($original as $item) {
420+
foreach ($original as $idx => $item) {
416421
if (!$item instanceof \stdClass) {
417422
return $new;
418423
}
@@ -430,7 +435,7 @@ private function rearrangeArray(array $original, array $new)
430435
$keyIsUnique = false;
431436
break;
432437
}
433-
$uniqueIdx[$value] = true;
438+
$uniqueIdx[$value] = $idx;
434439
}
435440

436441
if ($keyIsUnique) {
@@ -439,43 +444,54 @@ private function rearrangeArray(array $original, array $new)
439444
}
440445
}
441446

442-
if ($uniqueKey) {
443-
$newIdx = array();
444-
foreach ($new as $item) {
445-
if (!$item instanceof \stdClass) {
446-
return $new;
447-
}
447+
if (!$uniqueKey) {
448+
return $new;
449+
}
448450

449-
if (!property_exists($item, $uniqueKey)) {
450-
return $new;
451-
}
451+
$newRearranged = [];
452+
$changedItems = [];
452453

453-
$value = $item->$uniqueKey;
454+
foreach ($new as $item) {
455+
if (!$item instanceof \stdClass) {
456+
return $new;
457+
}
454458

455-
if ($value instanceof \stdClass || is_array($value)) {
456-
return $new;
457-
}
459+
if (!property_exists($item, $uniqueKey)) {
460+
return $new;
461+
}
458462

459-
if (isset($newIdx[$value])) {
460-
return $new;
461-
}
463+
$value = $item->$uniqueKey;
462464

463-
$newIdx[$value] = $item;
465+
if ($value instanceof \stdClass || is_array($value)) {
466+
return $new;
464467
}
465468

466-
$newRearranged = array();
467-
foreach ($uniqueIdx as $key => $item) {
468-
if (isset($newIdx[$key])) {
469-
$newRearranged [] = $newIdx[$key];
470-
unset($newIdx[$key]);
469+
470+
if (isset($uniqueIdx[$value])) {
471+
$idx = $uniqueIdx[$value];
472+
// Abandon rearrangement if key is not unique in new array.
473+
if (isset($newRearranged[$idx])) {
474+
return $new;
471475
}
476+
477+
$newRearranged[$idx] = $item;
478+
} else {
479+
$changedItems[] = $item;
472480
}
473-
foreach ($newIdx as $item) {
474-
$newRearranged [] = $item;
481+
482+
$newIdx[$value] = $item;
483+
}
484+
485+
$idx = 0;
486+
foreach ($changedItems as $item) {
487+
while (array_key_exists($idx, $newRearranged)) {
488+
$idx++;
475489
}
476-
return $newRearranged;
490+
$newRearranged[$idx] = $item;
477491
}
478492

479-
return $new;
493+
ksort($newRearranged);
494+
$newRearranged = array_values($newRearranged);
495+
return $newRearranged;
480496
}
481497
}

0 commit comments

Comments
 (0)