How to change rows with columns in matrix with same width? - php

Values in my matrix is
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
I want to put second columns as rows starting with from column 2 as (the same width and length of matrix)
Like that
2 5 8
11 14 1
4 7 10
13 3 6
9 12 15
I use that function I know its return the same matrix with no changes
function change($matrix){
$new_matrix =array();
foreach ($matrix as $row => $values) {
foreach ($values as $columns=>$value) {
$new_matrix[$row][$columns] = $value;
}
}
return $new_matrix;
}
I can use that function but it very bad structure
function change1($matrix)
{
$list= array(
array($matrix[0][1],$matrix[1][1],$matrix[2][1]),
array($matrix[3][1],$matrix[4][1],$matrix[0][0]),
array($matrix[1][0],$matrix[2][0],$matrix[3][0] ),
array($matrix[4][0],$matrix[0][2],$matrix[1][2] ),
array($matrix[2][2],$matrix[3][2],$matrix[4][2] ),
);
return $list;
}

$data = array(
array(1, 2, 3),
array(4, 5, 6),
array(7, 8, 9),
array(10, 11, 12),
array(13, 14, 15),
);
array_unshift($data, null);
$newData = call_user_func_array('array_map', $data);
$newData = array_chunk(
array_merge_recursive($newData[1], $newData[0], $newData[2]),
3
);
var_dump($newData);

If you have PHP 5.5+ can simply use array_column(). Then merge all columns in linear array. Example:
$arr1 = array_column($arr, 1);
$arr2 = array_column($arr, 0);
$result = array_merge($arr1, $arr2);
$arr1 = array_column($arr, 2);
$result = array_chunk(array_merge($result, $arr1), 3);
foreach($result as $val){
foreach($val as $v){
echo $v . ' ';
}
echo '<br />';
}

Related

How to duplicate array and sum up those array values in PHP

I have values 1,2,3 and it will create another value like below and produce results by summing. As there are 3 values so that it will create three arrays. if it were 5 values then 5 such arrays are required.
1 2 3
1 2 3
1 2 3
Result is : 1 3 6 5 3
What I am doing is :
$a=[1,2,3];
$b=$a;
$c=$a;
$d=[];
array_push($a,0,0);
array_unshift($b,0);
array_push($b,0);
array_unshift($c,0,0);
$d = array_map(function () {
return array_sum(func_get_args());
}, $a,$b,$c);
print_r($d);
I am not able to find the way to do this for more values than 3 and dynamically. So that I have to just put the values and it gives me the result. I am not asking for the code but you can help me with that how I should approach it. Thanks.
I recommend a linear approach with no preparations or padding or data bloat.
Use the indexes and simple arithmetic to add values to their desired element in the output.
Code: (Demo)
$array = range(1, 3);
$result = [];
foreach ($array as $shifter => $unused) {
foreach ($array as $index => $value) {
$key = $shifter + $index;
$result[$key] = ($result[$key] ?? 0) + $value;
}
}
var_export($result);
// [1, 3, 6, 5, 3]
This is very clean, readable, maintainable, and most efficient.
While $shifter = 0, $key will be 0, 1 then 2; forming [1, 2, 3].
While $shifter = 1, $key will be 1, 2 then 3; forming [1, 3, 5, 3].
While $shifter = 2, $key will be 2, 3 then 4; forming [1, 3, 6, 5, 3].
If you're using PHP 7.4+ you can use the below...
// Ensure the keys are indexed not associative.
$input = array_values( [ 1, 2, 3, 4, 5 ] );
// Create rows.
$rows = [];
foreach ( $input as $key => $value ) {
$rows[ $key ] = array_merge( array_fill( 0, $key, 0 ), $input );
}
// Sum values.
$output = array_map( function() {
return array_sum( func_get_args() );
}, ...$rows );
If you're using a PHP version below 7.4 you can do...
// Ensure the keys are indexed not associative.
$input = array_values( [ 1, 2, 3 ] );
// Create rows.
$rows = [];
foreach ( $input as $key => $value ) {
$rows[ $key ] = array_merge( array_fill( 0, $key, 0 ), $input );
}
// Sum values.
$output = call_user_func_array( 'array_map', array_merge( [ function() {
return array_sum( func_get_args() );
} ], $rows ) );
I'm thinking using an offset makes sense, it's the same as your approach, except I'm adding a 0 using array_fill
$arr = [1,2,3];
$result = [];
$offset = 0;
for($i = 0; $i < count($arr); $i++) {
$result = array_map(function () {
return array_sum(func_get_args());
}, $result, array_merge(array_fill(0, $offset, 0), $arr));
$offset++;
}
var_dump($result);
The advantage of using this is that it uses very little memory even for a very large initial array.

Index Third last occurrence of the integer, 1 in array

Below my code. I want to find the index/position of third last occurrence of the integer 1
$arr = array(2, 3, 1, 4, 5, 6, 1, 1,10,11,12,1);
$result = [];
foreach($arr as $key => $val){
$result[$val][] = $key;
}
echo end($result[1]);// 11 but it should be 6
Try this:
$arr = array(2, 3, 1, 4, 5, 6, 1, 1,10,11,12,1);
$result = [];
foreach($arr as $key => $val){
$result[$val][] = $key;
}
//count total record of $result[1] and third last index
$count = count($result[1]);
$thirdLastIndex = $count-3;
echo isset($result[1][$thirdLastIndex]) ? $result[1][$thirdLastIndex] : 'No record';
Demo

Count element in multidimensional array

I have one problem with PHP array. I have the following array:
$arr = array(
1 => array(1, 2),
2 => array(1,2,3),
3 => array(4,array(4,4,4))
);
I want to know how many element in total.
Ex:
echo count($arr); // result: 3
but I want: 7
I want to do this without loop.
Do any one know, please help?
Take one of this
$arr = array(
1 => array(1, 2),
2 => array(1, 2, 3),
3 => array(4, array(4, 4, 4))
);
// iterate over values to find out their size/
var_dump(array_reduce($arr, function($count, $inner_array)
{ return $count + sizeof($inner_array); }, 0));
// merge all value to one big array
var_dump(count(call_user_func_array('array_merge', $arr)));
// create new array with counts of items
var_dump(array_sum(array_map('sizeof', $arr)));
<?php
$arr = array(
1 => array(1, 2),
2 => array(1,2,3),
3 => array(4,array(4,4,4))
);
$sum = 0;
foreach($arr as $a => $b) {
$sum += count($b);
}
echo $sum;
?>
$arr = array(
1 => array(1, 2),
2 => array(1,2,3),
3 => array(4,array(4,4,4))
);
$count = 0;
foreach ($arr as $level) {
$count+= count($level);
}
echo $count;
If your array as follows you can use another method for get 7
$arr = array(
1 => array(1, 2),
2 => array(1,2,3),
3 => array(4,8)
);
echo (count($arr, COUNT_RECURSIVE) - count($arr));

Merge two flat arrays and omit values from one array when the other array has more occurrences of the same value

I want to merge every element of two arrays, BUT if a value is in both arrays, then only add the values from the array which has the biggest amount of that element. The result array does not need to be sorted in any special way, but I did it here for readability.
Sample input:
$array1 = [1, 4, 7, 3, 3, 3];
$array2 = [4, 0, 3, 4, 9, 9];
Desired result:
[0, 1, 3, 3, 3, 4, 4, 7, 9, 9]
//a2 a1 a1 a1 a1 a2 a2 a1 a2 a2
Note, this will be used on big arrays, with unknown integer values. Is there a good way to do this that doesn't require too much time/processing power?
Try this:
<?php
$array1 = [1, 4, 7, 3, 3, 3];
$array2 = [4, 0, 3, 4, 9, 9];
function min_merge($arr1, $arr2) {
$arr1 = array_count_values($arr1);
$arr2 = array_count_values($arr2);
foreach ($arr2 as $index => $arr)
if (!isset($arr1[$index]) || $arr > $arr1[$index])
$arr1[$index] = $arr;
foreach ($arr1 as $index => $arr)
for ($i = 0; $i < $arr; $i++)
$final[] = $index;
return $final;
}
print_r(min_merge($array1, $array2));
Output:
Array (
[0] => 1
[1] => 4
[2] => 4
[3] => 7
[4] => 3
[5] => 3
[6] => 3
[7] => 0
[8] => 9
[9] => 9
)
Unsorted, but it contains all the numbers from [0, 1, 3, 3, 3, 4, 4, 7, 9, 9].
$count[0] = array_count_values($arr1);
$count[1] = array_count_values($arr2);
$out = array();
array_map(function($e) use(&$out, $count){
$n1 = (isset($count[0][$e])) ? $count[0][$e] : 0;
$n2 = (isset($count[1][$e])) ? $count[1][$e] : 0;
$next = ($n2 > $n1) ? array_fill(0, $n2, $e) : array_fill(0, $n1, $e);
$out = array_merge($out, $next);
}, array_keys($count[0] + $count[1]));
print_r($out);
My modernized rewrite of #DaveChen's answer using PSR-12 coding standards and eliminating single-use declarations. This approach uses one loop to determine the greater count for numbers shared by both value-count arrays, then a second loop to populate the result array. (Demo)
$counts1 = array_count_values($array1);
foreach (array_count_values($array2) as $number => $count) {
if ($count > ($counts1[$number] ?? 0)) {
$counts1[$number] = $count;
}
}
$result = [];
foreach ($counts1 as $number => $count) {
array_push($result, ...array_fill(0, $count, $number));
}
var_export($result);
My modernized rewrite of #Expedito's answer which does not abuse the array_map() (when array_map()'s return value is not used, use array_walk() for functional style programming), uses a foreach() loop to eliminate variable scope issues, and generally implements D.R.Y. techniques. (Demo)
$counts1 = array_count_values($array1);
$counts2 = array_count_values($array2);
$result = [];
foreach ($counts1 + $counts2 as $num => $cnt) {
array_push(
$result,
...array_fill(
0,
max($counts1[$num] ?? 0, $counts2[$num] ?? 0),
$num
)
);
}
var_export($result);
And I wanted to add a new approach of my own, despite the fact that it may or may not perform better than the other two snippets. The script makes one pass over the first value count arrays to populate a temporary array which demands which numbers from the first array should be represented in the result array. Then it isolates value intersections from the first array, value differences from the second array, then merges them. (Demo)
$counts1 = array_count_values($array1);
$counts2 = array_count_values($array2);
$keepFrom1 = array_keys(
array_filter(
$counts1,
fn($count, $number) => ($counts2[$number] ?? 0) <= $count,
ARRAY_FILTER_USE_BOTH
)
);
var_export(
array_merge(
array_intersect($array1, $keepFrom1),
array_diff($array2, $keepFrom1)
)
);
probably not the most optimized but
<?php
$one=[1, 4, 7, 3, 3, 3];
$two=[4, 0, 3, 4, 9, 9];
sort($one);
sort($two);
foreach($one as $el)
{
$combined[]=$el;
if (array_search($el,$two))
{
unset($two[array_search($el,$two)]);
}
}
foreach($two as $el)
{
$combined[]=$el;
}
sort($combined);
print_r($combined);
?>

PHP Array Combine and Sum

I have multiple arrays, that get generated when a for loop completes. Now I need to get the total of all these arrays together, but in order, for instance:
array1(2, 4, 6, 8, 10)
array2(2, 4, 6, 8, 10)
I need to add the 2's together, the 4's etc etc
Then put them into another array.
Some combination of array_combine and array_sum seems to be the solution but I can't figure it out.
Any help is greatly appreciated.
You could do this without any php function except count,
$limit = count($array1);
for ($i = 0; $i < $limit; $i++) {
$array_res[$i] = $array1[$i] + $array2[$i];
should work. This will combine your two arrays and add them in the same order. But be sure you used sort or ksort on both of your arrays before if you're not sure they are in the same order.
1st stlye
$a1 = array(
"a" => 2
,"b" => 0
,"c" => 5
);
$a2 = array(
"a" => 3
,"b" => 9
,"c" => 7
,"d" => 10
);
$a3 = array_merge($a1, $a2);
print_r($a3);
2nd style
$a3 = $a1;
foreach($a2 as $k=>$v) {
if(array_key_exists($k,$a3))
$a3[$k] + = $v;
else
$a3[$k] = $v;
}
You should use array_map():
$arr1 = array(2, 4, 6, 8, 10);
$arr2 = array(1, 2, 3, 4, 5);
$arr3 = array_map(
function($foo, $bar){
return $foo+$bar;
},
$arr1, $arr2
);
print_r($arr3); // outputs:
Array
(
[0] => 3
[1] => 6
[2] => 9
[3] => 12
[4] => 15
)
You can do something like this
$a = array(2, 4, 6, 8, 10);
$b = array(2, 4, 6, 8, 10);
$c = array_map("test", $a, $b);
function test($a, $b) {
return $a + $b;
}
print_r($c);
As far as I understand your question You want sum of all the similar digits in both the array:
<?php
$array1= array(2, 4, 6, 8, 10);
$array2=array(2, 4, 6, 8, 10);
$array_sum=array();
foreach($array1 as $key1=>$val1)
{
$sum=0;
foreach($array2 as $key2 => $val2)
{
if($val1==$val2)
{
$sum=$sum+$val1;
}
}
$array_sum[]=$sum;
}
print_r($array_sum);
?>

Categories