添加到数组(如果还不存在)


71

仅当元素不在数组中时才如何将其添加到数组中?我有以下内容:

$a=array();
// organize the array
foreach($array as $k=>$v){
    foreach($v as $key=>$value){
        if($key=='key'){
        $a[]=$value;
        }
    }
}

print_r($a);

//输出

Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 1
[4] => 2
[5] => 3
[6] => 4
[7] => 5
[8] => 6

)

相反,我希望$ a包含唯一值。(我知道我可以使用array_unique获得所需的结果,但我只是想知道)

Answers:


72

您必须对照in_array检查每个值:

$a=array();
// organize the array by cusip
foreach($array as $k=>$v){
    foreach($v as $key=>$value){
        if(!in_array($value, $a)){
        $a[]=$value;
        }
    }
}

1
随着输入数据量的增加,in_array()性能将越来越差。
mickmackusa


29

由于您似乎只有标量值,因此PHP的数组更像是一个哈希映射,因此您可以将值用作键来避免重复,并将$k键与它们关联以获取原始值:

$keys = array();
foreach ($array as $k => $v){
    if (isset($v['key'])) {
        $keys[$value] = $k;
    }
}

然后,您只需对其进行迭代以获取原始值:

$unique = array();
foreach ($keys as $key) {
    $unique[] = $array[$key]['key'];
}

这可能不是最明显和最全面的方法,但它在O(n)中非常有效。

in_array像其他建议的那样使用代替可能更直观。但是,您最终会得到不适用的O(n 2)(in_arrayO(n)中的算法)。即使将数组中的所有值压入并使用array_unique它也比in_arrayarray_unique将O(n ·log n)中的值排序,然后删除连续的重复项)要好。


这是我大多数时候喜欢的解决方案。数组键在php中摇滚。
cweiske 2011年

@xmedeko有一个建议的编辑,建议该开销O(n logn)不是O(n)因为“ PHP哈希的开销”,你们两个都可以在这里达成协议吗?:-)
Kos 2012年

IMHO array_unique保留原始订单值,而您的解决方案则不保留。
xmedeko 2012年


10

易于编写,但不是最有效的一种:

$array = array_unique(array_merge($array, $array_to_append));

这可能更快:

$array = array_merge($array, array_diff($array_to_append, $array));

伟大的解决方案,谢谢
Malus

1
根据我的IDE(PHPStorm,因为我尚未进行性能比较),第一个更快。当使用array_merge + array_diff时,PHPStorm给我一个“循环中使用资源密集型操作”的警告。
Catar4'1


4

尝试添加为键而不是值:

添加一个条目

function addEntry($entry) {
    $this->entries[$entry] = true;
}

获取所有条目

function getEntries() {
    return array_keys($this->enties);
}

这就是Java实现HashSets的方式(带有嵌入式HashMap和一个值,我认为它包含一个静态值new Object()
Erk,

3

如果您不关心键的顺序,则可以执行以下操作:

$array = YOUR_ARRAY
$unique = array();
foreach ($array as $a) {
    $unique[$a] = $a;
}

3

由于有很多方法可以实现所需的结果,并且提供!in_array()了很多人作为答案,并且OP已经提到了的使用array_unique,所以我想提供一些替代方案。

使用array_diff(php> = 4.0.1 || 5),您可以仅过滤掉不存在的新数组值。或者,您也可以使用键比较键和值array_diff_assochttp://php.net/manual/zh/function.array-diff.php

$currentValues = array(1, 2);
$newValues = array(1, 3, 1, 4, 2);
var_dump(array_diff($newValues, $currentValues));

结果:

Array
(
    [1] => 3
    [3] => 4
)

http://ideone.com/SWO3D1

另一种方法是使用array_flip将值分配为键,并使用进行比较isset,这将比in_array大型数据集执行得快得多。同样,这仅过滤掉当前值中尚不存在的新值。

$currentValues = [1, 2];
$newValues = [1, 3, 1, 4, 2];
$a = array();
$checkValues = array_flip($currentValues);
foreach ($newValues as $v) {
    if (!isset($checkValues[$v])) {
        $a[] = $v;
    }
}

结果:

Array
(
    [0] => 3
    [1] => 4
)

http://ideone.com/cyRyzN

通过这两种方法,您都可以array_merge将唯一的新值附加到当前值。

  1. http://ideone.com/JCakmR
  2. http://ideone.com/bwTz2u

结果:

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


1

您可以尝试使用“ in_array”:

function insert_value($value, &$_arr) {
    if (!in_array($value, $_arr)) {
        $_arr[] = $value;
    }
}

0

甘博的想法,使代码工作:

$array = array('111111','222222','3333333','4444','5555', 
'AAAAAA', 'BBBBBB', 'CCC', 'DDDDDDD', 'EEEEEEEE', 'FFFFFF', 'GGG',
'AAAAAA', 'BBBBBB', 'CCC', 'DDDDDDD', 'EEEEEEEE', 'FFFFFF', 'GGG',
'222222', 
'666666', '777777', 'HHHH');

print_r($array);

$keys= array();
foreach ($array as $k => $v){
    if (isset($v['value'])) {
        $keys[$v] = $k;
    }
}
$unique = array();
foreach ($keys as $key) {
    $unique[] = $array[$key];
}
print "<br><br>";
print_r($unique);

给出以下内容:

Array
(
    [0] => 111111
    [1] => 222222
    [2] => 3333333
    [3] => 4444
    [4] => 5555
    [5] => AAAAAA
    [6] => BBBBBB
    [7] => CCC
    [8] => DDDDDDD
    [9] => EEEEEEEE
    [10] => FFFFFF
    [11] => GGG
    [12] => AAAAAA
    [13] => BBBBBB
    [14] => CCC
    [15] => DDDDDDD
    [16] => EEEEEEEE
    [17] => FFFFFF
    [18] => GGG
    [19] => 222222
    [20] => 666666
    [21] => 777777
    [22] => HHHH
)

Array
(
    [0] => 111111
    [1] => 222222
    [2] => 3333333
    [3] => 4444
    [4] => 5555
    [5] => AAAAAA
    [6] => BBBBBB
    [7] => CCC
    [8] => DDDDDDD
    [9] => EEEEEEEE
    [10] => FFFFFF
    [11] => GGG
    [12] => 666666
    [13] => 777777
    [14] => HHHH
)

0

有了array_flip()它可能看起来像这样:

$flipped = array_flip($opts);
$flipped[$newValue] = 1;
$opts = array_keys($flipped);

array_unique()-像这样:

$opts[] = $newValue;
$opts = array_values(array_unique($opts));

请注意,array_values(...)如果将数组以JSON格式导出到JavaScript,则需要它。array_unique()一个人就可以简单地设置重复键,而无需重建其余元素。因此,在转换为JSON之后,这将产生对象,而不是数组。

>>> json_encode(array_unique(['a','b','b','c']))
=> "{"0":"a","1":"b","3":"c"}"

>>> json_encode(array_values(array_unique(['a','b','b','c'])))
=> "["a","b","c"]"

-3

试试这个代码,我从这里得到的

$input = Array(1,2,3,1,2,3,4,5,6);
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.