array_diff 在对象数组上
array_diff on array of objects
我遇到了 PHP 函数 array_diff 的问题。
在这两种情况下,我都在相同 class 对象的数组上使用它。
第一种情况:
public function findFreeUsers($weekId)
{
$em = $this->getEntityManager();
$week = $em->getRepository(Week::class)->findOneBy(["id" => $weekId]);
$busyWeeks = $em->getRepository(Week::class)->findWeekBetweenDates($week);
$busyUsers = array();
foreach ($busyWeeks AS $busyWeek) {
$tmp = $em->getRepository(UserWeek::class)->findBy(["week" => $busyWeek["id"]]);
if ($tmp != null) {
foreach($tmp AS $singleWeek) {
$busyUsers[] = $singleWeek->getUser();
}
}
}
$allUsers = $em->getRepository(User::class)->findAll();
$freeUsers = array_diff($allUsers, $busyUsers);
return $freeUsers;
}
第二种情况:
public function findFreeCars($weekId)
{
$em = $this->getEntityManager();
$week = $em->getRepository(Week::class)->findOneBy(["id" => $weekId]);
$busyWeeks = $em->getRepository(Week::class)->findWeekBetweenDates($week);
$busyCars = array();
foreach ($busyWeeks AS $busyWeek) {
$tmp = $em->getRepository(CarWeek::class)->findBy(["week" => $busyWeek["id"]]);
if ($tmp != null) {
foreach($tmp AS $singleWeek) {
$busyCars[] = $singleWeek->getCar();
}
}
}
$allCars = $em->getRepository(Car::class)->findAll();
$freeCars = array_diff($allCars, $busyCars);
return $freeCars;
}
我正在转储这些数组,它们都是具有相同 class.
对象的数组
在第一种情况下有效,在第二种情况下我有:
Error: Object of class AppBundle\Entity\Car could not be converted to string
你不应该使用 array_diff 来比较数组和对象。
要正确执行此操作,您需要使用 array_udiff() 并且需要定义对象之间的 "difference" 的含义。
例如,如果对象具有不同的 id,它们可能会有所不同
function compareCars(Car $objA, Car $objB) {
return $objA->getId() <=> $objB->getId();
}
$diff = array_udiff($allCars, $busyCars, 'compareCars')
如果您将例如 ComparableInterface 添加到每个 class 中,您希望通过 id 仅使用一种方法 getId() 进行比较,那么您可以利用多态性
的好处
interface ComparableInterface
{
public function getId();
}
class Car implements ComparableInterface
{
public function getId()
{
return $this->id;
}
//rest of the class source
}
function compareCars(ComparableInterface $objA, ComparableInterface $objB) {
return $objA->getId() <=> $objB->getId();
}
甚至为每个对象定义 returns compare() 方法,无论它是否相等
interface AdvancedComparableInterface extends ComparableInterface
{
public function compare(ComparableInterface $obj);
}
class Car implements AdvancedComparableInterface
{
public function getId()
{
return $this->id;
}
public function compare(ComparableInterface $obj)
{
return $this->getId() <=> $obj->getId();
}
//rest of the class source
}
function compareCars(AdvancedComparableInterface $objA, ComparableInterface $objB) {
return $objA->compare($objB);
}
如您所见,您可以使用多种方式来定义对象是否与另一个对象相同。例如,您可以通过 VIN
比较的汽车
旁注:
就学说的性能而言,循环执行查询不是一个好主意。如果您通过将 busyWeek 的 id 作为数组传递给 findBy 方法来进行一次查询会更好。
我遇到了 PHP 函数 array_diff 的问题。
在这两种情况下,我都在相同 class 对象的数组上使用它。
第一种情况:
public function findFreeUsers($weekId)
{
$em = $this->getEntityManager();
$week = $em->getRepository(Week::class)->findOneBy(["id" => $weekId]);
$busyWeeks = $em->getRepository(Week::class)->findWeekBetweenDates($week);
$busyUsers = array();
foreach ($busyWeeks AS $busyWeek) {
$tmp = $em->getRepository(UserWeek::class)->findBy(["week" => $busyWeek["id"]]);
if ($tmp != null) {
foreach($tmp AS $singleWeek) {
$busyUsers[] = $singleWeek->getUser();
}
}
}
$allUsers = $em->getRepository(User::class)->findAll();
$freeUsers = array_diff($allUsers, $busyUsers);
return $freeUsers;
}
第二种情况:
public function findFreeCars($weekId)
{
$em = $this->getEntityManager();
$week = $em->getRepository(Week::class)->findOneBy(["id" => $weekId]);
$busyWeeks = $em->getRepository(Week::class)->findWeekBetweenDates($week);
$busyCars = array();
foreach ($busyWeeks AS $busyWeek) {
$tmp = $em->getRepository(CarWeek::class)->findBy(["week" => $busyWeek["id"]]);
if ($tmp != null) {
foreach($tmp AS $singleWeek) {
$busyCars[] = $singleWeek->getCar();
}
}
}
$allCars = $em->getRepository(Car::class)->findAll();
$freeCars = array_diff($allCars, $busyCars);
return $freeCars;
}
我正在转储这些数组,它们都是具有相同 class.
对象的数组在第一种情况下有效,在第二种情况下我有:
Error: Object of class AppBundle\Entity\Car could not be converted to string
你不应该使用 array_diff 来比较数组和对象。
要正确执行此操作,您需要使用 array_udiff() 并且需要定义对象之间的 "difference" 的含义。
例如,如果对象具有不同的 id,它们可能会有所不同
function compareCars(Car $objA, Car $objB) {
return $objA->getId() <=> $objB->getId();
}
$diff = array_udiff($allCars, $busyCars, 'compareCars')
如果您将例如 ComparableInterface 添加到每个 class 中,您希望通过 id 仅使用一种方法 getId() 进行比较,那么您可以利用多态性
的好处interface ComparableInterface
{
public function getId();
}
class Car implements ComparableInterface
{
public function getId()
{
return $this->id;
}
//rest of the class source
}
function compareCars(ComparableInterface $objA, ComparableInterface $objB) {
return $objA->getId() <=> $objB->getId();
}
甚至为每个对象定义 returns compare() 方法,无论它是否相等
interface AdvancedComparableInterface extends ComparableInterface
{
public function compare(ComparableInterface $obj);
}
class Car implements AdvancedComparableInterface
{
public function getId()
{
return $this->id;
}
public function compare(ComparableInterface $obj)
{
return $this->getId() <=> $obj->getId();
}
//rest of the class source
}
function compareCars(AdvancedComparableInterface $objA, ComparableInterface $objB) {
return $objA->compare($objB);
}
如您所见,您可以使用多种方式来定义对象是否与另一个对象相同。例如,您可以通过 VIN
比较的汽车旁注:
就学说的性能而言,循环执行查询不是一个好主意。如果您通过将 busyWeek 的 id 作为数组传递给 findBy 方法来进行一次查询会更好。