5

I have a 2 dimensional array like this

array( array( 'column1' => 10, 'column2' => 11 ), array( 'column1' => 25, 'column2' => 137 ), array( 'column1' => 21, 'column2' => 58 ) ) 

The keys column1 and column2 are fixed. They do not change.

I need to perform various functions on the data in this 2D array. The various functions can be grouped in two ways:

  • Row-wise first
  • Column-wise first

An example for Row-wise first functions,

I want to sum up all the numbers row-wise first before multiplying by columns.

So the expected behavior is (10+11) * (25+137) * (21+58)

An example for Column-wise first functions,

I want to sum up all the numbers column-wise first before multiplying by rows.

So the expected behavior is (10+25+21)*(11+137+58)

I have no problems writing out my own component functions. In the above, I need only two component functions sum and product

function sum (adden1, adden2) { return adden1 + adden2; } function product (multiplicant1, multiplicant2) { return multiplicant1 * multiplicant2; } 

The problem is the mapping. I want to reduce the number of for-loops I need to write. I want my code to be more modular because there are situations where the required behaviors are like:

  1. Perform this for each row 100-(column1+column2) / column2 and then sum up all the results.

There are too many formulae I need to work. But I am very confident that basically it is all a mixture of either performing row-wise first or column-wise first.

Hope to get some suggestions on the mapping of the values to the functions.

UPDATE:

Eventually I redesign my architecture to make this issue go away. So this question no longer is applicable to me.

1
  • I don't think so, it can be done without for OR foreach loop. Commented Feb 5, 2013 at 4:54

3 Answers 3

1

Row wise is the easiest to map:

$a = array( array( 'column1' => 10, 'column2' => 11 ), array( 'column1' => 25, 'column2' => 137 ), array( 'column1' => 21, 'column2' => 58 ) ); echo array_product(array_map('array_sum', $a)), "\n"; 

Column wise needs a utility function to grab all columns together into one array:

echo array_product(array( array_sum(array_column($a, 'column1')), array_sum(array_column($a, 'column2')) )), PHP_EOL; function array_column(array $a, $column) { return array_map(function($item) use ($column) { return $item[$column]; }, $a); } 
Sign up to request clarification or add additional context in comments.

2 Comments

I like your code better than bmused. But I like that bmused put the links to array_map and array_walk. I didn't know those functions exist.
@kimsia yes, linking to the manual is convenient :) just type "php.net/" followed by any function name to achieve the same.
1

You have to iterate over the array somehow. Take a look at array_map and array_walk.

Here's an example:

<?php $input = array( array( 'column1' => 10, 'column2' => 11 ), array( 'column1' => 25, 'column2' => 137 ), array( 'column1' => 21, 'column2' => 58 ) ); echo 'Row wise : ', array_product(array_map( function($row){ return $row['column1'] + $row['column2']; }, $input)), '<br/>'; $output = array(0,0); array_walk($input, function($val, $key, &$output){ $output[0] += $val['column1']; $output[1] += $val['column2']; }, &$output); echo 'Column wise : ', array_product($output); ?> 

Comments

0

Regardless of the orientation of your 2d array, making mapped calls of array_sum() then a single call to array_product() is the most concise functional-style approach.

To process row-wise, pass the original array to the aforementioned process.

To process column-wise, simply "transpose" your array -- in other words convert your columnar data into rows. Typically, the preferred approach is also the most concise: array_map(null, ...$array). HOWEVER, if you ever have just one row of data in your 2d array, then only a 1d array will be produced and that will break the aforementioned process which requires a 2d array. For this reason, choose a transposing technique that is stable.

Code: (Demo)

$array = [ ['column1' => 10, 'column2' => 1], ['column1' => 3, 'column2' => 5], ['column1' => 2, 'column2' => 4] ]; // multiply summed rows (10+1)×(3+5)×(2+4) = 528 echo array_product( array_map( 'array_sum', $array ) ); echo "\n---\n"; // multiply summed column (10+3+2)×(1+5+4) = 150 echo array_product( array_map( 'array_sum', array_map( fn(...$cols) => $cols, ...$array ) ) ); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.