2016-06-07 6 views
1

Ich habe das folgende Array, in dem ich das total_volume für alle Einträge zusammenfassen soll, wo die Quelle und das Ziel identisch sind.PHP summieren Array-Einträge, wo zwei Schlüssel den gleichen Wert haben

Array (
[0] => Array 
    (
     [source] => ABC 
     [target] => DEF 
     [total_volume] => 10 
    ) 

[1] => Array 
    (
     [source] => ABC 
     [target] => GHI 
     [total_volume] => 5 
    ) 
[2] => Array 
    (
     [source] => ABC 
     [target] => DEF 
     [total_volume] => 5 
    ) 
) 

Das resultierende Array sollte wie folgt aussehen:

ResultArray (
[0] => Array 
    (
     [source] => ABC 
     [target] => DEF 
     [total_volume] => 15 
    ) 

[1] => Array 
    (
     [source] => ABC 
     [target] => GHI 
     [total_volume] => 5 
    ) 
) 

Mein erster Gedanke zu llop durch das bestehende Array sein würde und prüfen über eine verschachtelte Schleife über die ResultArray, ob ein Eintrag mit dem passenden Quellen- Ziel-Paar existiert bereits.

Gibt es einen anderen Weg mit array_walk() oder einer ähnlichen Methode?

Vielen Dank im Voraus für Ihre Hilfe!

+0

Ich kann es mit rohen Code machen, brauchen Sie genau mit 'array_walk' oder roh ?? –

+0

Ich wäre mit jeder Lösung glücklich, da ich keine Ahnung hatte, wie ich dieses Problem lösen könnte. So roh funktioniert es gut für mich. Vielen Dank im Voraus! – mxzwrnz

+0

Mögliches Duplikat von [Summe der Werte erhalten, die denselben Wert für das Schlüssel-PHP-Array haben] (http://stackoverflow.com/questions/37654630/get-sum-of-values-which-have-same-value-for-key -php-array) –

Antwort

2

nicht schön, aber heren, wie ich es mit einer verschachtelten foreach tun würde;

$aStartingArray = array(); 
$aStartingArray[] = array('source'=>'ABC', 'target' => 'DEF', 'total_volume' => 10); 
$aStartingArray[] = array('source'=>'ABC', 'target' => 'GHI', 'total_volume' => 5); 
$aStartingArray[] = array('source'=>'ABC', 'target' => 'DEF', 'total_volume' => 5); 


$aSortedArray = array(); 

foreach ($aStartingArray as $aArray) { 

    $bSet = false; 

    foreach ($aSortedArray as $iPos => $aTempSortedArray) { 

     if(
      $aTempSortedArray['source'] == $aArray['source'] && 
      $aTempSortedArray['target'] == $aArray['target']){ 

      $aSortedArray[$iPos]['total_volume'] += $aArray['total_volume']; 

      $bSet = true; 
     } 

    } 

    if(!$bSet) { 

     $aSortedArray[] = array(
      'source' => $aArray['source'], 
      'target' => $aArray['target'], 
      'total_volume' => $aArray['total_volume'] 
      ); 
    } 
} 


var_dump($aSortedArray); 
1

Dies ist ein schneller Versuch (sorry, es zweimal array_walk verwendet)

<?php 

$a = [ 
    ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 10 ], 
    ['source' => 'ABC', 'target' => 'GHI', 'total_volume' => 5 ], 
    ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 5 ], 
]; 

$tmp = []; 

array_walk($a, function (&$item, $key) use (&$tmp) { 
    $resKey = $item['source'].'_'.$item['target']; 
    if (!isset($result[$resKey])) { 
     $result[$resKey] = 0; 
    } 
    $tmp[$resKey] += $item['total_volume']; 
}); 

$result = []; 
array_walk($tmp, function (&$item, $key) use (&$result) { 
    list ($source, $target) = explode('_', $key); 
    $result[] = ['source' => $source, 'target' => $target, 'total_volume' => $item]; 
}); 

var_dump($result); 
+0

Ich habe es auch für die Antwort versucht, aber nicht abgeschlossen, gute Antwort. –

1

Wie wäre es damit? Ein bisschen kürzer denke ich.

$a = [ 
    ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 10 ], 
    ['source' => 'ABC', 'target' => 'GHI', 'total_volume' => 5 ], 
    ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 5 ], 
]; 
$result = $result2 = []; 
array_walk($a, function(&$item, $key) use(&$result) { 
    if(! isset($result[$item['source']])) 
     $result[$item['source']] = []; 
    if(! isset($result[$item['source']][$item['target']])) 
     $result[$item['source']][$item['target']] = 0; 
    $result[$item['source']][$item['target']] += $item['total_volume']; 
}); 
foreach($result as $key => $val) { 
    foreach($val as $k => $v) { 
     $result2[] = [$key,$k,$v]; 
    } 
} 
print_r($result2); 
0

Eine andere Alternative. Nicht gut, aber funktioniert.

$arr = [ 
    ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 10 ], 
    ['source' => 'ABC', 'target' => 'GHI', 'total_volume' => 5 ], 
    ['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 5 ], 
]; 

$res = $resulrArr = []; 
foreach($arr as $record){ 
    $record = array_values($record); 
    $res[$record[0].'_'.$record[1]] = !empty($res[$record[0].'_'.$record[1]]) ? $res[$record[0].'_'.$record[1]] + $record[2] : $record[2]; 
} 

$resulrArr = array_map(function($v,$k){ 
    $data = explode('_',$k); 
    $resulrArr['source'] = $data[0]; 
    $resulrArr['target'] = $data[1]; 
    $resulrArr['total_volume'] = $v; 
    return $resulrArr; 
},$res,array_keys($res)); 

echo '<pre>'; print_r($resulrArr); 
Verwandte Themen