PHP:比较数组中的对象

时间:2014-06-10 00:48:25

标签: php arrays

如何比较数组内的对象?

我有一个动态填充的simpleXML个对象数组(长度未知)

有没有一种快速的方法来比较数组中的所有这些对象并排除重复项?

由于ID字段在每个simpleXML对象中都不同所以它变得有点困难所以我需要在比较中省略它。

例如简单的短版本:

Array
(
    [0] => SimpleXMLElement Object
        (
            [ID] => 556
            [FIRST] => JOHN
            [MID] => SimpleXMLElement Object
                (
                )

            [LAST] => SMITH


        )

    [1] => SimpleXMLElement Object
        (
            [ID] => 557
            [FIRST] => JOHN
            [MID] => SimpleXMLElement Object
                (
                )

            [LAST] => SMITH
        )

)

这些是2个重复。我需要确认并删除一个。

这是我到目前为止所做的:

    $noDups = array();
    foreach($arr as $key=>$value)
    {
                    if (0 == $key) {
                         $noDups[] = $value;
                         continue;
                    }
        foreach($arr as $_key=>$_value)
        {

            $first = ( ((string)$value->FIRST) !== ((string)$_value->FIRST) )?true:false;
            $mid = ( ((string)$value->MID) !== ((string)$_value->MID) )?true:false;
            $last = ( ((string)$value->LAST) !== ((string)$_value->LAST) )?true:false;

            if ($first && $mid && $last)
            {
                array_push($noDups, $value);
            }
        }
    }

但如果你知道我的意思,我找不到这段代码sexy

2 个答案:

答案 0 :(得分:1)

从数组中删除重复项的最有效方法是array_unique函数。

如文档中所述,当且仅当它们的字符串表示相等((string) $elem1 === (string) $elem2)时,此函数才认为两个元素相等。

对象的字符串represantion可以通过__toString魔法处理。

SimpleXMLElement已实施__toString,因此,为了从比较中排除ID,您需要覆盖此方法:

class ComparableXMLElement extends SimpleXMLElement
{
    public function __toString()
    {
        //In order to exclude ID from comparison we need to return an unique string based only on specific attributes
        return md5("F".$this->FIRST."_M".$this->MID."_L".$this->LAST);
    }
}

然后您需要使用ComparableXMLElement个对象填充数组,而不是SimpleXMLElement和简单

$noDups = array_unique($arr);

会做到这一点。


作为旁注:

由于所有比较运算符(例如!==)已经返回一个布尔值,因此不需要使用三元运算符(?:)。 而不是

$first = ( ((string)$value->FIRST) !== ((string)$_value->FIRST) )?true:false;

你应该写

$first = ((string)$value->FIRST) !== ((string)$_value->FIRST);

答案 1 :(得分:0)

您可以遍历数组并使用key = what matters

构建关联数组
$uniq = array();
foreach($arr as $obj) {
  $uniq[$obj['FIRST'] . '::' . $obj['MID'] . '::' . $obj['LAST']] = $obj;
}