1

I have a PHP array thats like this:

$a1 = [
    [ 'buyer'=>"ACME", 'fees1'=>"100", 'seller'=>"XYZ plc", 'fees2'=>"200", 'item'=>"Bricks" ],
    [ 'buyer'=>"ACME", 'fees1'=>"110", 'seller'=>"XYZ plc", 'fees2'=>"220", 'item'=>"Bricks" ],
    [ 'buyer'=>"XYZ Plc", 'fees1'=>"200", 'seller'=>"ACME", 'fees2'=>"300", 'item'=>"Cement" ],
    /* and so on and on */
];

So the report I am trying to produce is this:

    BRICKS---CEMENT
ACME----220------300
XYZ-----440------200
--------------------
        660------500

I am out of my wits trying the best possible way to iterate it. As of now I have managed to filter out the UNIQUE buyers and sellers and items into separate arrays. Any help/tip will be much appreciated.

Thanks ahead

6
  • The source of $a1 isn't by pure chance a relational database with all those niffty aggregate functions? Commented Feb 18, 2015 at 10:14
  • Nope, i got a1 from a csv file. I wish it WAS a relational database Commented Feb 18, 2015 at 10:38
  • 1
    I couldn't get how you are arriving at the numbers in the output from fees1 and fees2. Would appreciate if you can include that in the question as well. Commented Feb 18, 2015 at 11:16
  • sorry about that, its basically adding all the buyer fees (fees1), and seller fees(fees2) for each item, example, ACME fees for bricks comes to 100+110 = 220 Commented Feb 18, 2015 at 11:46
  • Just to be on the safe side ... could you please make up an example that is bullet-proof and double- no tripple-checked? 100+110=210 ;-) Commented Feb 18, 2015 at 11:57

3 Answers 3

1

There's most likely a more elegant solution, but anyway

<?php
$dataset = [
    [ 'buyer'=>"ACME", 'fees1'=>"100", 'seller'=>"XYZ plc", 'fees2'=>"200", 'item'=>"Bricks" ],
    [ 'buyer'=>"ACME", 'fees1'=>"110", 'seller'=>"XYZ plc", 'fees2'=>"220", 'item'=>"Bricks" ],
    [ 'buyer'=>"XYZ plc", 'fees1'=>"200", 'seller'=>"ACME", 'fees2'=>"300", 'item'=>"Cement" ],
    /* and so on and on */
];

$columns = array_unique(array_column($dataset, 'item'));
//sort($columns);

// create a template with all possible items (as key) and value 0
$template = array_combine(
    $columns,
    array_pad( array(), count($columns), 0)
);


$result = [];
foreach( $dataset as $row ) {
    // if we haven't seen this seller before
    if ( !isset($result[ $row['seller'] ]) ) {
        // create a template with all possible items but each having 0-value
        $result[ $row['seller'] ] = $template;
    }
    // same for buyer
    if ( !isset($result[ $row['buyer'] ]) ) {
        $result[ $row['buyer'] ] = $template;
    }


    // now comes the tricky part
    // remember: $result[$row['seller']] === array('Bricks'=>sumFeeBricks, 'Cemtent'=>sumFeeCement)
    // i.e. $result[$row['seller']]['Cemtent'] += <something> increases sumFeeCement in the array representing the seller in $result
    // $row['item'] tells you which element within $result[$row['seller']] you want to increase
    // ==> $result[$row['seller']][$row['item']] += ....

    // increase sumFee of the sold item by fee2 for the seller
    $result[$row['seller']][ $row['item'] ] += $row['fees2'];

    // increase sumFee of the sold item by fee1 for the buyer
    $result[$row['buyer']][ $row['item'] ] += $row['fees1'];
}
var_export($result);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank You Mister. You sir, get my plus.
0

Just iterate over the array creating a new multidimensional one. No need to translate the givven array directly to the desired output.

Comments

0

I came with an idea of solving it, if you don't have such a function like array_column (i.e. PHP 5.4.10)

<?php
// we assume, the data is organised in such a way: first buyer/seller/whatever then fees1/fees2/etc, item can be at the end or beginning
$a1 = [
    [ 'buyer'=>"ACME", 'fees1'=>"100", 'seller'=>"XYZ plc", 'fees2'=>"200", 'item'=>"Bricks" ],
    [ 'buyer'=>"ACME", 'fees1'=>"110", 'seller'=>"XYZ plc", 'fees2'=>"220", 'item'=>"Bricks" ],
    [ 'buyer'=>"XYZ Plc", 'fees1'=>"200", 'seller'=>"ACME", 'fees2'=>"300", 'item'=>"Cement" ],
    /* and so on and on */
];
function process($obj, $arr){ // we process a single row of $a1
        $data = array(); // first we create an indexed array for storing a single key and its value
        foreach($obj as $key=>$val){
                $key = strtolower($key);
                $val = strtolower($val);
                $data[] = array($key=>$val);
        }
        for($i=0;$i<sizeof($data);$i++){ // we iterate over this array
                $key = array_pop(array_keys($data[$i])); // we've got current key
                $val = $data[$i][$key]; // we've got current value, company
                if(preg_match("/buyer|seller/", $key)){ // if it's seller or buyer or whatever we want just edit
                        $next_key = array_pop(array_keys($data[$i+1])); // we take the next element of $data which is $key=>$value, next key i.e. fees1
                        $next_val = $data[$i+1][$next_key]; // we take its value e.g. 100
                        $arr[$val]+=$next_val; // we put the money for company, and adding them up
                }
        }
        return $arr; // the end of processing a single row of $a1
}
$data = array(); // first we create the data split into items buckets
foreach($a1 as $obj){
        foreach($obj as $key=>$val){
                $key = strtolower($key); // ACME or AcMe, no difference
                $val = strtolower($val);
                if(preg_match("/item/", $key)){
                        $data[$val][] = $obj;
                }
        }
}
print_r($data);
$final = array(); // we store the result for items
foreach($data as $item=>$obj){ // we iterate over items
        $arr = array(); // variable for one item, for next we'll start  from empty array
        foreach($obj as $val){ // we process each row for item
                $arr = process($val, $arr);
        }
        $final[$item] = $arr; // we put processed data to key which is item
}
$total = array(); // we store the total result
foreach($final as $val){
        foreach($val as $key=>$prize){
                    $total[$key]+=$prize; // we add up all money for a single company
        }
}

print_r($final);
print_r($total);
?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.