【问题标题】:replace duplicate fom stdclass array php [duplicate]替换重复的stdclass数组php [重复]
【发布时间】:2014-09-28 01:41:18
【问题描述】:

当我打印$online_performers 变量时,我想获得id 2 的唯一值。我需要先将它们转换为标准数组还是没有它可能? (删除所有重复项)。请检查我的新代码。

 Array
        (
            [0] => stdClass Object
            (
                [id] => 1
                [username] => Sample1
            )
            [1] => stdClass Object
            (
                [id] => 2
                [username] => Sample1
            )
           [2] => stdClass Object
            (
                [id] => 2
                [username] => Sample1
            )
           [3] => stdClass Object
            (
                [id] => 4
                [username] => Sample4
            )
        )



to
    Array
        (
            [0] => stdClass Object
            (
                [id] => 1
                [username] => Sample1
            )
            [1] => stdClass Object
            (
                [id] => 4
                [username] => Sample4
            )
        )

【问题讨论】:

  • 您确定要释放包含属性 [id] = 2 的两个类吗???
  • 是的,它们是重复的
  • 是的,但这通常意味着您保留其中一个并删除其中一个?
  • 对不起我的错误我更新了我的代码。我想消除重复
  • 重复项是否总是在一起,或者您想检查整个数组是否有可能的重复项。

标签: php arrays


【解决方案1】:

为此,PHP 有一个名为 array_filter() 的函数:

$filtered = array_filter($array, function($item) {
    static $counts = array();
    if(isset($counts[$item->id])) {
        return false;
    }

    $counts[$item->id] = true;
    return true;
});

注意static 关键字的用法。如果在函数内部使用,则意味着在第一次调用函数时,变量只会被初始化一次。这提供了跨多个函数调用保留查找表$counts 的可能性。


在您告诉的 cmets 中,如果 X 出现不止一次,您还寻找一种方法来删除所有具有 id X 的项目。您可以使用以下算法,该算法使用查找表 $ids 来检测 id 多于一个的元素并将其删除(全部):

$array = array("put your stdClass objects here");

$ids = array();
$result = array();

foreach($array as $item) {
    if(!isset($ids[$item->id])) {
        $result[$item->id]= $item;
        $ids[$item->id] = true;
    } else {
        if(isset($result[$item->id])) {
            unset($result[$item->id]);
        }
    }
}

$result = array_values($result);
var_dump($result);

【讨论】:

  • 嗨,这可以完全删除重复项吗?
  • 你的意思是删除每个出现多次的项目?
  • @vishal 我不喜欢 fancy 方式。您需要遍历数组,计算出现次数并在之后的第二个循环中删除重复项。
  • @vishal 检查我的更新
  • 您好,您的第一个算法运行良好,第二个运行不正常我将数组设置为 $array = array($online_performers);但它不能正常工作。在您的第一个算法中,它会删除重复项,但它会保留 1,例如,如果 id=2 在数组中出现 3 次,它将替换两个并保留 1,而不是我想删除所有重复的项目。谢谢。
【解决方案2】:

如果您不关心更改您的 keys,您可以通过一个简单的循环来做到这一点:

$aUniq = array ();
foreach($array as $obj) {
    $aUniq[$obj->id] = $obj;
}

print_r($aUniq);

【讨论】:

    【解决方案3】:

    假设我们有:

    $array = [
       //items 1,2,3 are same
       (object)['id'=>1, 'username'=>'foo'],
       (object)['id'=>2, 'username'=>'bar'],
       (object)['id'=>2, 'username'=>'baz'],
       (object)['id'=>2, 'username'=>'bar']
    ];
    

    那么重复取决于你的意思。例如,如果是这样的:具有相同id 的两个项目被视为重复项,那么:

    $field = 'id';
    
    $result = array_values(
       array_reduce($array, function($c, $x) use ($field)
       {
          $c[$x->$field] = $x;
          return $c;
       }, [])
    );
    

    但是,如果这是关于应该匹配的所有字段,那么情况就不同了:

    $array = [
       //1 and 3 are same, 2 and 3 are not:
       (object)['id'=>1, 'username'=>'foo'],
       (object)['id'=>2, 'username'=>'bar'],
       (object)['id'=>2, 'username'=>'baz'],
       (object)['id'=>2, 'username'=>'bar']
    ];
    

    您需要以某种方式确定您的价值行。最简单的方法是serialize()

    $result = array_values(
       array_reduce($array, function($c, $x)
       {
          $c[serialize($x)] = $x;
          return $c;
       }, [])
    );
    

    但这可能会很慢,因为您将序列化整个对象结构(因此您不会看到对小对象的性能影响,但对于复杂结构和大量对象来说,这听起来很糟糕)

    此外,如果您不关心结果数组中的键,则可以省略 array_values() 调用,因为它仅用于使键数字连续。

    【讨论】:

    • 这非常优雅,但它正在检查用户名,他想检查 [id] 字段。
    • @RiggsFolly 我也为此做了一个选项(见第一个解释)
    • 啊,谢谢错过了,现在我只需要弄清楚这一切意味着什么。
    • 嗨,谢谢,在我的情况下,我已经合并了两个数组,所以我不想保留任何其他具有相同 id 的输入,例如只保留 1 和 2,并从你制作的数组中删除其他 id2 ( object)['id'=>1, 'username'=>'foo'], (object)['id'=>2, 'username'=>'bar']
    • 还有.. 什么?如果它们是重复的,那么根据定义,保留哪一个并不重要
    猜你喜欢
    • 2018-09-09
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    相关资源
    最近更新 更多