对于那些不喜欢 array_splice
的人,因为它涉及到 "array by reference" &
,这里有一个 array_slice
变体。
面向对象和单元测试。
<?php declare(strict_types=1);
namespace App\API\Common\Sorter;
final class ArraySorter
{
public function moveItem(int $fromIndex, int $toIndex, array $array): array
{
$movingItem = $array[$fromIndex];
$slicingArray = $array;
unset($slicingArray[$fromIndex]);
$startingItems = array_slice($slicingArray, 0, $toIndex);
$endingItems = array_slice($slicingArray, $toIndex);
$splicedArray = array_merge($startingItems, [$movingItem], $endingItems);
return $splicedArray;
}
}
单元测试
<?php declare(strict_types=1);
namespace App\API\Tests\Unit\Common;
use App\API\Common\Sorter\ArraySorter;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase;
final class ArraySorterTest extends TestCase
{
private ArraySorter $arraySorter;
protected function setUp(): void
{
$this->arraySorter = new ArraySorter();
}
public function testMoveItem(int $fromIndex, int $toIndex, array $expectedArray): void
{
$array = ['a', 'b', 'c', 'd'];
$result = $this->arraySorter->moveItem($fromIndex, $toIndex, $array);
Assert::assertSame($expectedArray, $result);
}
public function moveItemProvider(): array
{
return [
'move first forward' => ['fromIndex' => 0, 'toIndex' => 1, 'expectedArray' => ['b', 'a', 'c', 'd']],
'move middle forward' => ['fromIndex' => 1, 'toIndex' => 2, 'expectedArray' => ['a', 'c', 'b', 'd']],
'move middle back' => ['fromIndex' => 2, 'toIndex' => 1, 'expectedArray' => ['a', 'c', 'b', 'd']],
'move last back' => ['fromIndex' => 3, 'toIndex' => 2, 'expectedArray' => ['a', 'b', 'd', 'c']],
];
}
}