PHP - 数组到 'unique'
PHP - array to 'unique'
我有一个如下所示的数组:
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"
}
...
}
现在我想制作这个数组 'unique'(以便稍后能够创建一些 select 框)。
我已经有一个按预期工作的函数......不幸的是,完成一个非常大的数组需要几个小时:(
有什么想法可以让这个功能更快吗?
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
提前致谢
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;
}
}
对于非常大的数组,要考虑的另一件事是将值复制到新数组,这会增加内存占用。如果 return 数组的键是 0 索引的连续整数对你来说并不重要,你可以从原始数组中删除重复项:
$helparray = array();
foreach($array as $key => $row)
{
if(!(array_key_exists($row[$uniqueCol], $helparray)))
{
$helparray[$row[$uniqueCol]] = true;
}
else
{
unset($array[$key]);
}
}
$deduplicated = [];
foreach ($array as $value) {
$deduplicated[$value['country']] = $value;
}
只需利用键是唯一的这一事实,您就可以在一次传递中自动对数组进行重复数据删除。如果您不喜欢新密钥,请在之后使用 array_values()
。
我有一个如下所示的数组:
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"
}
...
}
现在我想制作这个数组 'unique'(以便稍后能够创建一些 select 框)。 我已经有一个按预期工作的函数......不幸的是,完成一个非常大的数组需要几个小时:(
有什么想法可以让这个功能更快吗?
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
提前致谢
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;
}
}
对于非常大的数组,要考虑的另一件事是将值复制到新数组,这会增加内存占用。如果 return 数组的键是 0 索引的连续整数对你来说并不重要,你可以从原始数组中删除重复项:
$helparray = array();
foreach($array as $key => $row)
{
if(!(array_key_exists($row[$uniqueCol], $helparray)))
{
$helparray[$row[$uniqueCol]] = true;
}
else
{
unset($array[$key]);
}
}
$deduplicated = [];
foreach ($array as $value) {
$deduplicated[$value['country']] = $value;
}
只需利用键是唯一的这一事实,您就可以在一次传递中自动对数组进行重复数据删除。如果您不喜欢新密钥,请在之后使用 array_values()
。