【问题标题】:PHP - array to 'unique'PHP - 数组为“唯一”
【发布时间】:2015-07-01 22:28:08
【问题描述】:

我有一个如下所示的数组:

array(43197) {
 [0]=> array(4) {
     ["id"]=> string(5) "10038"
     ["country"]=> string(7) "Andorra"
     ["city"]=> string(16) "Andorra la Vella"
     ["name"]=> string(25) "Andorra la Vella Heliport" 
    }
 [1]=> array(4) {
     ["id"]=> string(5) "10040"
     ["country"]=> string(20) "United Arab Emirates"
     ["city"]=> string(17) "Abu Dhabi Emirate"
     ["name"]=> string(11) "Ras Sumeira" 
    }
 [2]=> array(4) {
     ["id"]=> string(5) "10041"
     ["country"]=> string(20) "United Arab Emirates"
     ["city"]=> string(13) "Dubai Emirate"
     ["name"]=> string(27) "Burj al Arab Resort Helipad" 
    }
 [3]=> array(4) {
     ["id"]=> string(5) "10042"
     ["country"]=> string(20) "United Arab Emirates"
     ["city"]=> string(13) "Dubai Emirate"
     ["name"]=> string(13) "Dubai Skydive" 
    }
 [4]=> array(4) {
     ["id"]=> string(5) "14243"
     ["country"]=> string(20) "United Arab Emirates"
     ["city"]=> string(13) "Dubai Emirate"
     ["name"]=> string(15) "Dubai Creek SPB" 
    }
 [5]=> array(4) {
     ["id"]=> string(5) "29266"
     ["country"]=> string(20) "United Arab Emirates"
     ["city"]=> string(17) "Abu Dhabi Emirate"
     ["name"]=> string(18) "Yas Island Airport" 
    }
...
}

现在我想让这个数组“唯一”(以便以后能够创建一些选择框)。 我已经有一个按预期工作的函数......不幸的是,完成一个非常大的数组需要几个小时:(

任何想法如何使这个功能更快?

function array_to_unique(//This function returns an array of unique values by given array
    //Version: 2.0.0.0
    $array,
    $uniqueCol)
    {
    $returnArray = array();

    $count = count($array);
    echo '<br>array count previous unique is: ' .$count;

    //Do the if(isset($uniqueCol)) just once - this is more code but faster with long arrays    
    if(isset($uniqueCol))
        {
        $helparray = array();
        foreach($array as $row)
            {
            if(!(in_array($row[$uniqueCol],$helparray)))
                {
                $helparray[] = $row[$uniqueCol];
                $returnArray[] = $row;
                }
            }
        }
    else{
        foreach($array as $row)
            {
            if(!(in_array($row,$returnArray)))
                {$returnArray[] = $row;}
            }
        }

    $count = count($returnArray);
    echo '<br>array count after unique is: ' .$count;

    return $returnArray;
    }

这就是我调用函数的方式,例如:

array_to_unique($array); //This is okay
array_to_unique($array,'country'); //This is very very slow

提前谢谢你

【问题讨论】:

  • 预期结果是什么?

标签: php arrays performance multidimensional-array associative-array


【解决方案1】:
$deduplicated = [];
foreach ($array as $value) {
    $deduplicated[$value['country']] = $value;
}

只需使用键是唯一的这一事实,您就可以在一次传递中自动对数组进行重复数据删除。如果您不喜欢新密钥,请在之后使用array_values()

【讨论】:

    【解决方案2】:

    in_array 的复杂度为O(n),这意味着它必须遍历所有元素。这会使您的代码变慢。

    如果值已经存在,您可以优化查找,使用哈希映射而不是搜索数组值。幸运的是,PHP 中的关联数组就是这样实现的,所以我们可以使用值作为键,并使用array_key_exists 进行查找。

    代替:

        $helparray = array();
        foreach($array as $row)
            {
            if(!(in_array($row[$uniqueCol],$helparray)))
                {
                $helparray[] = $row[$uniqueCol];
                $returnArray[] = $row;
                }
            }
    

    拍摄:

        $helparray = array();
        foreach($array as $row)
            {
            if(!(array_key_exists($row[$uniqueCol], $helparray)))
                {
                $helparray[$row[$uniqueCol]] = true;
                $returnArray[] = $row;
                }
            }
    

    对于非常大的数组要考虑的另一件事是将值复制到新数组中,这会增加内存占用。如果返回数组的键是 0 索引的连续整数对您来说并不重要,您可以从原始数组中删除重复项:

        $helparray = array();
        foreach($array as $key => $row)
            {
            if(!(array_key_exists($row[$uniqueCol], $helparray)))
                {
                $helparray[$row[$uniqueCol]] = true;
                }
                else
                {
                unset($array[$key]);
                }
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-05
      • 2019-04-05
      相关资源
      最近更新 更多