从数组中删除重复但忽略一个参数

时间:2015-06-28 05:12:19

标签: php arrays object multidimensional-array

我有一个由PHP对象组成的数组:

$objects[0] => $object->type => 'President'
               $object->name => 'Joe Blogs'
               $object->address => '123 Harry Street'

$objects[1] => $object->type => 'Secretary'
               $object->name => 'Joe Blogs'
               $object->address => '123 Harry Street'

$objects[2] => $object->type => 'Treasurer'
               $object->name => 'Jane Doe'
               $object->address => '456 Upton Street'

我想忽略type参数,最后得到:

$objects[0] => $object->type => 'President'
               $object->name => 'Joe Blogs'
               $object->address => '123 Harry Street'

$objects[2] => $object->type => 'Treasurer'
               $object->name => 'Jane Doe'
               $object->address => '456 Upton Street'

我尝试了一些不同的东西,其中一个是使用type循环取消设置参数foreach,然后尝试重置它,但我不确定如何绑定两个索引一起重置它们。另一个是尝试在select命令中使用union,但是它也没有正确地工作。

我只是不确定如何最好地管理type参数。

修改

我试图让查询更容易一些,它现在返回一个ID列表,我将在稍后获取地址信息。这是我想要过滤掉任何重复项的新数组。

    $items['president'][0] = '1'
                       [1] = '2'
                       [2] = '3'

    $items['secretary'][0] = '1'
                       [1] = '4'
                       [2] = '5'

我想要的是

$items['president'][0] = '1'
                   [1] = '2'
                   [2] = '3'

$items['secretary'][1] = '4'
                   [2] = '5'

这样更好吗? (注意:我可以使用两种数组结构,但第二种更好)

3 个答案:

答案 0 :(得分:1)

这应该适合你:

在这里,我只是浏览$objects中的每个对象。然后,我使用array_reduce()检查来自$unique的所有唯一对象,并检查是否有一个对象在nameaddress中具有与当前对象相同的值迭代。

如果name中没有任何具有相同值address$unique的对象,我会将其添加到其中。

<?php

    $unique = [];

    foreach($objects as $o) {

        $duplicate = array_reduce($unique, function($keep, $v)use($o){
            if($v->name == $o->name && $v->address == $o->address)
                return $keep = TRUE;
        }, FALSE);

        if(!$duplicate)
            $unique[] = $o;

    }

    print_r($unique);

?>

输出:

Array
(
    [0] => stdClass Object
        (
            [type] => President
            [name] => Joe Blogs
            [address] => 123 Harry Street
        )

    [1] => stdClass Object
        (
            [type] => Treasurer
            [name] => Jane Doe
            [address] => 456 Upton Street
        )

)

修改

从你使用新数组结构的更新问题开始,这样的事情应该有效:

就像您拥有一个具有唯一值的数组之前一样,还有一个数组可以跟踪您$unique数组中已有的值。然后你可以循环遍历你的数组,检查值是否已经在values数组中。

<?php

    $unique = [];
    $values = [];

    foreach($items as $keyOne => $arr) {

        foreach($arr as $keyTwo =>$v) {
            if(!in_array($v, $values)) {
                $unique[$keyOne][$keyTwo] = $v;
                $values[] = $v;
            }
        }
    }   

    print_r($unique);


?>

输出:

Array
(
    [president] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [secretary] => Array
        (
            [1] => 4
            [2] => 5
        )

)

答案 1 :(得分:1)

你可以使用array_unique,这个函数使用toString方法比较对象:

class obj{
    public $type;
    public $name;
    public $address;

    public function __construct($type, $name, $address){
        $this->type = $type;
        $this->name = $name;
        $this->$address = $address;
    }

    public function __toString(){
        return $this->name . $this->address;
    }
}


$objects = array(
    new obj('President','Joe Bogs','123 Harry Street'),
    new obj('Treasurer','Joe Bogs','123 Harry Street'),
    new obj('Secretary','Jane Doh','456 Harry Street'),
);

// array_unique compares the toString value if given objects
$unique = array_unique($objects);

或者,如果由于某些原因你不能在你的Object中使用__toString,编写你自己的独特函数,可以使用自定义函数进行比较,该函数返回你想要的unique_id:

function custom_array_unique($array, $function){
    $res = array();
    foreach($array as $o){
        if(!isset($res[$function($o)])) {
            $res[$function($o)] = $o;
        }
    }
    return array_values($res);
}

$unique2 = custom_array_unique($objects, function($obj){
    return $obj->name . $obj->address;
});

var_dump($unique2);

答案 2 :(得分:0)

您可以将type作为密钥,因此不会重复,如果您不想覆盖,您可以使用array_key_exists验证它是否存在,之后您可以array_values按要求获取订单,请参阅以下示例:

$newArray = array();
foreach($objects as $object){
    if(!array_key_exists($object->name, $newArray)){
        $newArray[$object->name] = $object;
    }
}
$newArray = array_values($newArray);
echo '<pre>';
print_r($newArray);