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

时间:2021-09-18 07:37:04

I need to count duplicated multidimensional array, remove this duplicates and push counted duplicated in new index.

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

Suppose a I have this array:

假设我有这个数组:

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] => 
            )

    )


 )

I want to remove duplicate array and create a new index count:

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

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

    )

 )

Is it possible?

可能吗?

3 个解决方案

#1


1  

This seems really ugly, but works.

这看起来很难看,但很有效。

Stacked foreach version:

叠加的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);

No foreach version:

没有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);

#2


1  

This function works:

这个功能有效:

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;
}

Part 1: Line 1 declares the function. Line 2 starts a foreach loop which runs through every element of the array, seeing if it matches any element before it, as checked usng the for loop on line 3, checking with the if statement on line 4. What line 4 actually does is, because you can't just compare the values of arrays to see if they're duplicates, it converts them into strings using print_r. If the strings match, line 5 deletes (unsets) the duplicate element. The @ stops it from giving you errors, because if the second element it is checking has already been deleted, you could get an error. Lines 6, 7 and 8 close the code blocks of the for loop, the foreach loop and the if statement. Now, you have an array without duplicates.

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

Part 2: Line 9 declares the $i variable, which will be incremented with every run through the foreach loop by the $i++; on line 12. This $i incrementing variable will be the new key for each element of the new array. Line 10 starts a foreach loop, which will loop through the array without duplicates produced by Part 1. Line 11 sets each element of the new array (the reindexed one) to the next element the foreach loop finds in the array from Part 1. Line 12 increments $i, as already mentioned. Line 13 closes the foreach loop's code block. Line 14 returns the new array, and line 15 closes the function. This leaves you with a reindexed version of the array with all duplicate first dimension elements removed.

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

Now you have a short and elegant way of doing it, and you know exactly how it works. Just copy and paste that at the top of your PHP, and wherever you have an array you need to do this to, just do this:

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

$array = deduplicate($array);

#3


0  

@Passerby

worked this way too

也是这样的

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"]++;

    }

What do you say?

你说什么?

#1


1  

This seems really ugly, but works.

这看起来很难看,但很有效。

Stacked foreach version:

叠加的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);

No foreach version:

没有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);

#2


1  

This function works:

这个功能有效:

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;
}

Part 1: Line 1 declares the function. Line 2 starts a foreach loop which runs through every element of the array, seeing if it matches any element before it, as checked usng the for loop on line 3, checking with the if statement on line 4. What line 4 actually does is, because you can't just compare the values of arrays to see if they're duplicates, it converts them into strings using print_r. If the strings match, line 5 deletes (unsets) the duplicate element. The @ stops it from giving you errors, because if the second element it is checking has already been deleted, you could get an error. Lines 6, 7 and 8 close the code blocks of the for loop, the foreach loop and the if statement. Now, you have an array without duplicates.

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

Part 2: Line 9 declares the $i variable, which will be incremented with every run through the foreach loop by the $i++; on line 12. This $i incrementing variable will be the new key for each element of the new array. Line 10 starts a foreach loop, which will loop through the array without duplicates produced by Part 1. Line 11 sets each element of the new array (the reindexed one) to the next element the foreach loop finds in the array from Part 1. Line 12 increments $i, as already mentioned. Line 13 closes the foreach loop's code block. Line 14 returns the new array, and line 15 closes the function. This leaves you with a reindexed version of the array with all duplicate first dimension elements removed.

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

Now you have a short and elegant way of doing it, and you know exactly how it works. Just copy and paste that at the top of your PHP, and wherever you have an array you need to do this to, just do this:

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

$array = deduplicate($array);

#3


0  

@Passerby

worked this way too

也是这样的

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"]++;

    }

What do you say?

你说什么?