从数组中删除出现少于两次的所有元素

3

我有一个这样的数组:

[0] = 2
[1] = 8
[2] = 7
[3] = 7

我希望最终得到的数组如下:

[0] = 7
[1] = 7

基本上,删除出现少于两次的所有元素。

是否有PHP函数可以实现这个功能?


2
array_count_values() 后跟一个计数大于1的过滤器,然后是 array_fill() 可能会起作用。 - Mark Baker
你能澄清一下问题吗?你想要做什么?要移除前两个元素吗? - kumar
关闭投票孤独无言备份... - imperium2335
8个回答

5

试试这个:

$ar1=array(2,3,4,7,7);
    $ar2=array();
    foreach (array_count_values($ar1) as $k => $v) {
        if ($v > 1) {
            for($i=0;$i<$v;$i++)
            {
            $ar2[] = $k;
            }
        }
    }
    print_r($ar2);

输出

数组([0] => 7 [1] => 7)


太好了,谢谢!不过很遗憾,fullybaked 没有重置数组键。 - imperium2335
对不起,什么?你一定是在开玩笑。 - hakre
4
@imperium2335 你可以更改接受答案,应选择最合适的答案。 - Yadav Chetan
2
+1,做事情总有不止一种方法,在这种情况下,阅读起来可能是最容易的。CPU参数让我笑了——好像它会有任何明显的区别一样... - AlexP
@imperium2335:最有效的解决方案?你的第二个循环完全是多余的。 - Sébastien Renauld
显示剩余10条评论

2

类似这样的代码可以工作,但你可能可以通过使用array_reduce和匿名函数来改进它

<?php

$originalArray = array(2, 8, 7, 7);

foreach (array_count_values($originalArray) as $k => $v) {
    if ($v < 2) {
        $originalKey = array_search($k, $originalArray);
        unset($originalArray[$originalKey]);
    }
}

var_dump(array_values($originalArray));

1
您可以使用array_count_values的组合(它将为您提供一个关联数组,其中值作为键,出现次数作为值),然后是一个简单的循环,如下所示:
$frequency = array_count_values($yourArray);
foreach ($yourArray as $k => $v) {
   if (!empty($frequency[$v]) && $frequency[$v] < 2) {
      unset($yourArray[$k]);
   }
}

我没有测试过它,但我认为它可以直接使用。请注意,您将两次循环遍历结果,而不是N ^ 2次,与array_search方法不同。这可以进一步改进,留给读者自己练习。

1
$testData = array(2,8,7,7,5,6,6,6,9,1);

$newArray = array();
array_walk(
    array_filter(
        array_count_values($testData),
        function ($value) {
            return ($value > 1);
        }
    ),
    function($counter, $key) use (&$newArray) {
        $newArray = array_merge($newArray,array_fill(0,$counter,$key));
    }
);

var_dump($newArray);

虽然这会产生严格的标准警告,为了避免这种情况,你需要一个中间阶段:

$testData = array(2,8,7,7,5,6,6,6,9,1);

$newArray = array();
$interim = array_filter(
    array_count_values($testData),
    function ($value) {
        return ($value > 1);
    }
);
array_walk(
    $interim,
    function($counter, $key) use (&$newArray) {
        $newArray = array_merge($newArray,array_fill(0,$counter,$key));
    }
);

var_dump($newArray);

1
这实际上比我想象的更难……无论如何……
 $input  = array(2, 8, 7, 7, 9, 9, 10, 10);
 $output = array();

 foreach(array_count_values($input) as $key => $value) {
   if ($value > 1) $output = array_merge($output, array_fill(0, $value, $key));
 }
 var_dump($output);  

1
不确定为什么您需要在array_merge()行中使用三元运算符:$output = array_merge($output, array_fill(0, $value, $key)); 应该可以完美地工作。 - Mark Baker
是的,谢谢。我原本以为在 array_fill 中必须明确指定起始索引。 - AlexP
只有在您计划使用 $output = $output + array_fill(0, $value, $key); 时,才会出现键冲突。 - Mark Baker

1
$arrMultipleValues = array('2','3','5','7','7','8','2','9','11','4','2','5','6','1');

function array_not_unique($input)    
{
    $duplicatesValues = array();

    foreach ($input as $k => $v)
    {
        if($v>1)
        {
        $arrayIndex=count($duplicatesValues);
        array_push($duplicatesValues,array_fill($arrayIndex, $v, $k));
        }    
    }

    return $duplicatesValues;
}

$countMultipleValue = array_count_values($arrMultipleValues);
print_r(array_not_unique($countMultipleValue));

0

这样做可以完成任务,也许不是最有效的方式。我自己对PHP还很陌生 :)

   <?php
$element = array();
$element[0] = 2;
$element[1] = 8;
$element[2] = 7;
$element[3] = 7;

$count = array_count_values($element);
var_dump($element);
var_dump($count);

$it = new RecursiveIteratorIterator( new RecursiveArrayIterator($count));

$result = array();
foreach ($it as $key=>$val){
    if ($val >= 2){
        for($i = 1; $i <= $val; $i++){
            array_push($result,$key);
        }
    }
}
var_dump($result);

?>

编辑:var_dump 只是为了让您在每个阶段看到发生了什么


0
有没有 PHP 函数可以做到这一点?
不,PHP 没有内置的函数(至少目前)可以直接实现这一点。
也就是说,如果你正在寻找一个能够做到这一点的函数,那么它需要在 PHP 用户空间中。我想引用你的问题下面的评论,这个评论已经建议了一个方法,如果你正在寻找这个方法的话:
array_count_values() 然后跟着一个 count >1 的过滤器,然后是一个 array_fill() 可能会起作用。
作者:Mark Baker 5 分钟前 如果这听起来有点神秘,那么他所提到的这些函数实际上都是 PHP 中的内置函数,因此我认为这最接近于“不行”的答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接