-3
지정된 getter의 반환 값으로 객체 배열을 정렬하는 방법은 무엇입니까?각 요소에 정의 된 getter를 사용하여 객체 배열을 정렬하는 방법은 무엇입니까?
예를 들어, 우리는 객체의 배열을 가지고 있습니다. 각 객체에는 DateTime 객체를 반환하는 'getCreatedAt'함수가 있습니다. 마지막 요소를 날짜별로 가져 오도록 배열을 정렬해야합니다.
지정된 getter의 반환 값으로 객체 배열을 정렬하는 방법은 무엇입니까?각 요소에 정의 된 getter를 사용하여 객체 배열을 정렬하는 방법은 무엇입니까?
예를 들어, 우리는 객체의 배열을 가지고 있습니다. 각 객체에는 DateTime 객체를 반환하는 'getCreatedAt'함수가 있습니다. 마지막 요소를 날짜별로 가져 오도록 배열을 정렬해야합니다.
내부 개체 관리를위한 PHP 특성 인 솔루션에 도달했습니다. 이제 우리는 엔티티에서이 특성을 단순히 구현하여 개체 배열을 비교할 수 있습니다. 이것은 코드입니다.
trait ObjectManagement
{
private function orderObjects(array $objects, string $getter, string $ordering): array
{
usort(
$objects,
[new ObjectAscDescOrderingByGetter($getter, $ordering), 'order']
);
return $objects;
}
}
class ObjectAscDescOrderingByGetter
{
private $getter;
private $ordering;
public function __construct(string $getter, string $ordering)
{
if (!in_array($ordering, ['ASC', 'DESC'])) {
throw new RuntimeException('Ordering type must be ASC or DESC.');
}
$this->getter = $getter;
$this->ordering = $ordering;
}
public function order($objectA, $objectB)
{
$getter = $this->getter;
$comparisonValueA = $objectA->$getter();
$comparisonValueB = $objectB->$getter();
if ($comparisonValueA === $comparisonValueB) {
return 0;
}
if ($this->ordering == 'DESC') {
return ($comparisonValueA > $comparisonValueB) ? -1 : 1;
} else {
return ($comparisonValueA > $comparisonValueB) ? 1 : -1;
}
}
}
우리는 특성이 어떤 경우에 가장 좋은 방법은 아니라는 것을 알고 있지만,이 경우 우리는이 주문 기능은 정적으로 다른 클래스에서 구현 될 수있는 코드이기 때문에 매우 도움이되었다고합니다.
class ObjectManagementTestCase extends TestCase
{
use ObjectManagement;
/**
* @dataProvider getOrderingCases
* @param array $datesToOrder
* @param array $datesExpectedOrder
* @param string $ordering
*/
public function testOrdering(array $datesToOrder, array $datesExpectedOrder, string $ordering)
{
$objectsToOrder = [];
foreach ($datesToOrder as $dateToOrder) {
$objectsToOrder[] = $this->getOrderableMock($dateToOrder);
}
$objectsExpectedOrder = [];
foreach ($datesExpectedOrder as $expectedDateOrder) {
$objectsExpectedOrder[] = $this->getOrderableMock($expectedDateOrder);
}
$result = $this->orderObjects($objectsToOrder, 'getCreatedAt', $ordering);
$this->assertEquals($objectsExpectedOrder, $result);
}
public function getOrderingCases()
{
return [
'Must order this in descendant manner.' => [
['2016-01-01', '2017-01-01', '2017-01-03', '2017-01-05'],
['2017-01-05', '2017-01-03', '2017-01-01', '2016-01-01'],
'DESC'
],
'Must order this in ascendant manner.' => [
['2016-01-01', '2017-01-03', '2017-01-01', '2017-01-05'],
['2016-01-01', '2017-01-01', '2017-01-03', '2017-01-05'],
'ASC'
],
];
}
private function getOrderableMock(string $date)
{
return new OrderableTestObject($date);
}
public function testThatInputArrayIsNotModified()
{
$objects = [
$this->getOrderableMock('2016-01-01'),
$this->getOrderableMock('2017-01-03'),
];
$this->orderObjects($objects, 'getCreatedAt', 'DESC');
$this->assertEquals(
[
$this->getOrderableMock('2016-01-01'),
$this->getOrderableMock('2017-01-03'),
],
$objects
);
}
public function testExceptionOnNotRecognizedOrder()
{
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Ordering type must be ASC or DESC.');
$this->orderObjects([], 'createdAt', '');
}
}
class OrderableTestObject
{
private $createdAt;
public function __construct(string $date)
{
$this->createdAt = new DateTime($date);
}
public function getCreatedAt(): DateTime
{
return $this->createdAt;
}
}
문제는 여기에 무엇입니까 .... 우리는 또한 테스트를 여기에두고
이 이제 실체에 우리의 유스 케이스인가? – ccKep
@ccKep 더 좋습니다. 고맙습니다. – Eloy
무슨 뜻입니까? 질문을 게시하고 즉시 답변을 올렸습니까? – ccKep