按索引和值对多维数组进行分组

时间:2013-06-19 02:54:35

标签: php arrays multidimensional-array duplicates grouping

我需要计算重复的多维数组,删除这些重复数据并推送计数重复的新索引。

假设我有这个数组:

Array
(
[0] => Array
    (
        [segments] => Array
            (
                [1] => Gcia de Auditoría Interna
                [0] => Auditoria Interna 1
            )

        [groups] => Array
            (
                [estados] => sp
                [cidade] => sumpaulo
            )

    )

[1] => Array
    (
        [segments] => Array
            (
                [2] => Gerencia Recursos Humanos
                [1] => Gcia Dpto Admin de Pers. y Rel. Laboral
                [0] => SubGcia Administración de Personal
            )

        [groups] => Array
            (
                [estados] => sp
                [cidade] => 
            )

    )

[2] => Array
    (
        [segments] => Array
            (
                [2] => Gerencia Recursos Humanos
                [1] => Gcia Dpto Admin de Pers. y Rel. Laboral
                [0] => SubGcia Administración de Personal
            )

        [groups] => Array
            (
                [estados] => sp
                [cidade] => 
            )

    )


 )

我想删除重复的数组并创建一个新的索引计数:

Array
(
[0] => Array
    (
        [segments] => Array
            (
                [1] => Gcia de Auditoría Interna
                [0] => Auditoria Interna 1
            )

        [groups] => Array
            (
                [estados] => sp
                [cidade] => sumpaulo
            )
        [total] = 1

    )

[1] => Array
    (
        [segments] => Array
            (
                [2] => Gerencia Recursos Humanos
                [1] => Gcia Dpto Admin de Pers. y Rel. Laboral
                [0] => SubGcia Administración de Personal
            )

        [groups] => Array
            (
                [estados] => sp
                [cidade] => 
            )
         [total] = 2

    )

 )

有可能吗?

3 个答案:

答案 0 :(得分:1)

这似乎非常丑陋,但有效。

堆叠foreach版本:

http://3v4l.org/Dve0M

$rst=array();
foreach($arr as $ele)
{
    foreach($rst as $i=>$candidate)
    {
        $key=null;
        foreach($ele as $k=>$subarr)
        {
            if(isset($candidate[$k]) && $candidate[$k]==$subarr)
            {
                $key=$i;
                break;
            }
        }
        if(!empty($key))
        {
            break;
        }
    }
    if(!empty($key)) $rst[$key]["total"]+=1;
    else $rst[]=array_merge($ele,array("total"=>1));
}
print_r($rst);

foreach版本:

http://3v4l.org/qUU3a

/* just to ensure the array is sorted.
 * if the array is already pre-sorted,
 * skip this part.
 */
usort($arr,function($a,$b){
    return strcmp(json_encode($a),json_encode($b));
});
$rst=array();
$cache=array();
while($p=array_shift($arr))
{
    if(empty($cache))
    {
        $cache[]=$p;
    }
    elseif($cache[0]==$p)
    {
        $cache[]=$p;
    }
    else
    {
        $rst[]=array_merge($cache[0],array("total"=>count($cache)));
        $cache=array();
        $cache[]=$p;
    }
}
if(!empty($cache))
{
    $rst[]=array_merge($cache[0],array("total"=>count($cache)));
}
print_r($rst);

答案 1 :(得分:1)

此功能有效:

function deduplicate($array) {
    foreach($array as $key => $subArray) { // First Part
        for($i = 0; $i < $key; $i++) {
            if (print_r($subArray, true) == @print_r($array[$i], true)) {
                unset($array[$i]);
            }
        }
    }
    $i = 0;                                // Second Part
    foreach($array as $subArray) {
        $newArray[$i] = $subArray;
        $i++;
    }
    return $newArray;
}

第1部分: 第1行声明了该函数。第2行启动一个foreach循环,它遍历数组的每个元素,看它是否与之前的任何元素匹配,因为检查了第3行的for循环,并使用if进行检查第4行的说法是,第4行实际上是这样做的,因为你不能只比较数组的值以查看它们是否重复,而是使用print_r将它们转换为字符串。如果字符串匹配,则第5行删除(unsets)重复元素。 @阻止它给你错误,因为如果它正在检查的第二个元素已被删除,你可能会收到错误。第6,7和8行关闭for循环,foreach循环和if语句的代码块。现在,你有一个没有重复的数组。

第2部分: 第9行声明了$i变量,该变量将在第12行foreach的{​​{1}}循环中每次运行时递增。此$i++;递增变量将是新键对于新数组的每个元素。第10行启动一个$i循环,循环遍历数组而没有第1部分产生的重复。第11行将新数组的每个元素(重新索引的数据)设置为foreach循环找到的下一个元素在第1部分的数组中,如前所述,第12行增加foreach。第13行关闭$i循环的代码块。第14行返回新数组,第15行关闭该函数。这将为您留下重新编制索引的数组版本,并删除所有重复的第一个维度元素。

现在你有一个简短而优雅的方式,你知道它是如何工作的。只需将其复制并粘贴到PHP的顶部,无论您需要执行此操作,只需执行此操作:

foreach

答案 2 :(得分:0)

@Passerby

也是这样做的

foreach($csv as $lines){
        $segstring = implode("+", $lines["segments"]);
        $groupstring = implode("+", $lines["groups"]);


        if(!isset($recsv[$segstring."+".$groupstring]["total"])){
            $recsv[$segstring."+".$groupstring] = $lines;
            $recsv[$segstring."+".$groupstring]["total"] = 0;
        }
        $recsv[$segstring."+".$groupstring]["total"]++;

    }

你说什么?