2013-06-19 32 views
0

我需要計數重複的多維數組,刪除此重複項,並推入計算在新索引中重複。通過索引和值組的多維數組

假設一個我有這樣的數組:

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 

    ) 

) 

這可能嗎?

+0

這當然也可以使用疊加'foreach's ... – Passerby

回答

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); 
+0

謝謝很多!它真的有用! @Passerby –

+0

從邏輯上講,您不需要三個嵌套循環來比較數組的元素。 – TheEnvironmentalist

+0

@TheEnvironmentalist是的,我意識到,我發佈後...... – Passerby

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

    } 

你說什麼?

+0

這很棒,因爲它使用數組鍵來確定重複,這可能會更快;但是你使用'implode'來構造密鑰,我不確定它是否會產生影響。無論如何,你的代碼看起來更清晰(如果你可以確保'[「segments」]和'[「groups」]都是一個一級的數組;我試圖避免觸及該部分使它更「通用」)。 – Passerby

+0

@Passerby謝謝您的關注!我更喜歡你的解決方案! –

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行啓動一個循環,循環遍歷數組的每個元素,看它是否與之前的任何元素相匹配,如第3行的for循環檢查,檢查第4行的if語句。第4行實際上是,因爲你不能只比較數組的值來查看它們是否重複,所以它會使用print_r將它們轉換爲字符串。如果字符串匹配,第5行刪除(unsets)重複的元素。 @阻止它給你提供錯誤,因爲如果它檢查的第二個元素已經被刪除,你可能會得到一個錯誤。第6,7和8行關閉了for循環,foreach循環和if語句的代碼塊。現在,你有一個沒有重複的數組。

第2部分: 第9行聲明瞭$i變量,這將與每一個通過foreach循環運行由$i++;上線12被遞增該$i遞增變量將是新的數組的每個元素的新的密鑰。第10行啓動了一個foreach循環,循環遍歷數組而不會複製第1部分生成的數組。第11行將新數組(重新索引的)的每個元素設置爲循環在第1部分數組中找到的下一個元素。正如已經提到的那樣,12個增量$i。第13行關閉了foreach循環的代碼塊。第14行返回新數組,第15行關閉該函數。這會爲您留下一個數組的重新索引版本,並刪除所有重複的第一個維度元素。

現在你有一個簡短而優雅的方式來做它,你確切地知道它是如何工作的。只需複製並粘貼在你的PHP的頂部,只要你有一個數組,你需要做這,只是這樣做:

$array = deduplicate($array);