Merging arrays within an array, preserving numeric index - php

Array_merge and array_merge_recursive are not working as desired, creating more indexes instead of pushing the arrays together and retaining the index number. See below for input/desired output:
Array (
[0] => array(
[0] => "string1",
[1] => "string2",
[2] => "string3"
),
[1] => array(
[0] => "string4",
[1] => "string5",
[2] => "string6"
),
[2] => array(
[0] => "string7",
[1] => "string8",
[2] => "string9"
)
)
Desired Output:
Array (
[0] => array("string1","string4","string7"),
[1] => array("string2","string5","string8"),
[2] => array("string3","string6","string9")
)
EDIT:
Perhaps not the best example; I want to achieve the same results but with an unequal number of keys in each nested array. See below for a better example:
<?php
$array = Array (
[0] => array(
[0] => "string1",
[1] => "string2",
[2] => "string3"
),
[1] => array(
[0] => "string4",
[1] => "string5",
[2] => "string6"
),
[2] => array(
[0] => "string7",
[1] => "string8",
[2] => "string9"
),
[3] => array(
[0] => "string10",
[1] => "string11",
[2] => "string12"
)
);
$output=array();
for($0=0;$j<count($array[0]);$j++){
$output[$j] = array();
}
for($i=0;$i<count($array);$i++){
for($0=0;$j<count($array[0]);$j++){
$output[$j] = array_push($output[$j],$column_values[$i][$j]);
}
}
?>
But when I do this, I get the correct number of keys in my $output array, but they all contain a bool(false). Any help?
This is the desired output:
Array (
[0] => array("string1","string4","string7","string10"),
[1] => array("string2","string5","string8","string11"),
[2] => array("string3","string6","string9","string12")
)

This is to make an array just for this structure of array, so you may change the code depanding on your needs ...
<pre>
<?php
$array = array(array("string1","string2","string3"),array("string4","string5","string6"),array("string7","string8","string9"));
$output=array();
for($i=0;$i<count($array[0]);$i++){
for($j=0;$j<count($array[0]);$j++){
$output[$i][$j] = $array[$j][$i];
}
}
print_r($output);
?>
</pre>

This is for your 'second' situation:
<?php
$array = array(array("string1","string2","string3"),array("string4","string5","string6"),array("string7","string8","string9"),array("string10","string11","string12"));
$output=array();
for($i=0;$i<count($array[0]);$i++){
for($j=0;$j<=count($array[0]);$j++){
$output[$i][$j] = $array[$j][$i];
}
}
print_r($output);
?>

Got it. Last loop should simply array_push($output[$j],$column_values[$i][$j]); instead of trying to set the variable $output[$j] = array_push(Yadda,yadda).

Related

PHP: Modify array's elements sequence

I've an php array that I've got from Excel file, for example:
$arrayOne
Array
{
[0] => Array
{
[0] => 0_age
[1] => 1_academic id
[2] => 2_name
[3] => 3_sex
}
[1] => Array
{
[0] => 0_18
[1] => 1_110291
[2] => 2_Jason
[3] => 3_Male
}
}
and in the mid of proccess, the array value from index [0] that consist data from Excel Header set into duallistbox for elimination and sorting then set into new array $newArray. So then, I got this array result:
$newArray
Array
{
[0] => Array
{
[0] => 2_name
[1] => 1_academic id
[2] => 3_sex
}
}
And I expect the system also can eliminate and sorting the data of array from index [1] that consist of Excel Data.
So the expected result is like this:
$expectedArray
Array
{
[0] => Array
{
[0] => 2_Jason
[1] => 1_110291
[2] => 3_Male
}
}
anyone know idea or how to solve this case? I've add an id(e.g: 0_) in each of array value that maybe useful for sorting.
Thanks
Edited
The sorting is based on the id that have been set on each value of array, so each element on array index [1] from $arrayOne is reset into new sequence adapted to same id from $newArray.
One way
<?php
$arr = array(
array
(
"0_age",
"1_academic id",
"2_name",
"3_sex",
),
array
(
"0_18",
"1_110291",
"2_Jason",
"3_Male",
),
array
(
"0_28",
"1_110291111",
"2_Jason Second",
"3_Female",
)
);
?>
<pre>
<?php
$new_array = array();
$count = 0;
foreach($arr as $a){
if($count==0){
}else{
$new_array[] = array(
$arr[0][0] => $a[0],
$arr[0][1] => $a[1],
$arr[0][2] => $a[2],
$arr[0][3] => $a[3],
);
}
$count=$count+1;
}
print_r($new_array);
?>
</pre>
Output
Array
(
[0] => Array
(
[0_age] => 0_18
[1_academic id] => 1_110291
[2_name] => 2_Jason
[3_sex] => 3_Male
)
[1] => Array
(
[0_age] => 0_28
[1_academic id] => 1_110291111
[2_name] => 2_Jason Second
[3_sex] => 3_Female
)
)
Second Way that exactly match with your output
$new_array = array();
$count = 0;
foreach($arr as $a){
if($count==0){
}else{
$new_array[] = array(
//$a[0],
$a[2],
$a[1],
$a[3],
);
}
$count=$count+1;
}
print_r($new_array);
Output:
Array
(
[0] => Array
(
[0] => 0_18
[1] => 1_110291
[2] => 2_Jason
[3] => 3_Male
)
[1] => Array
(
[0] => 0_28
[1] => 1_110291111
[2] => 2_Jason Second
[3] => 3_Female
)
)
You can search, Sort and remove any field. Update on the basis of your requirement.

How to sum the numbers of two arrays

This is probably not so hard, but I have searched for a while with no luck so any help will be appreciated.
I'm working in PHP with two arrays which contain a number of multidimensional arrays each with a set of two values. The 2 arrays looks something like this:
Array
(
[0] => Array
(
[0] => 3206.63
[1] => 815.47
)
[1] => Array
(
[0] => 5024.71
[1] => 803.73
)
[2] => Array
(
[0] => 3290.36
[1] => 625.02
)
//...
)
Array
(
[0] => Array
(
[0] => 3138.87
[1] => 819.8
)
[1] => Array
(
[0] => 5000.24
[1] => 810.87
)
[2] => Array
(
[0] => 3221.15
[1] => 668.58
)
//...
)
And I need to achieve this:
Array
(
[0] => Array
(
[0] => 6345.5
[1] => 1635.27
)
[1] => Array
(
[0] => 10024.95
[1] => 1614.6
)
[2] => Array
(
[0] => 6511.51
[1] => 1293.6
)
//...
)
This should work for you:
(Here i loop though each innerArray with foreach and use array_sum() to get the sum of all values of each innerArray)
<?php
$arr = array(
array(
3206.63,
815.47
),
array(
5024.71,
803.73
),
array(
3290.36,
625.02
)
);
$result = array();
foreach($arr as $v)
$result[] = array_sum($v);
print_r($result);
?>
Output:
Array ( [0] => 4022.1 [1] => 5828.44 [2] => 3915.38 )
If you have 2 Arrays you can use this:
$result = array();
foreach($arr1 as $k => $v)
$result[] = array_sum($arr1[$k]) + array_sum($arr2[$k]);
print_r($result);
EDIT:
From your updated question, this should work for you:
<?php
$arr1 = array(
array(
3206.63,
815.47
),
array(
5024.71,
803.73
),
array(
3290.36,
625.02
)
);
$arr2 = array(
array(
3138.87,
819.8
),
array(
5000.24,
810.87
),
array(
3221.15,
668.58
)
);
$sums = array();
foreach ($arr1 as $key => $value) {
$sums[$key][] = $arr1[$key][0] + $arr2[$key][0];
$sums[$key][] = $arr1[$key][1] + $arr2[$key][1];
}
print_r($sums);
?>
Output:
Array
(
[0] => Array
(
[0] => 6345.5
[1] => 1635.27
)
[1] => Array
(
[0] => 10024.95
[1] => 1614.6
)
[2] => Array
(
[0] => 6511.51
[1] => 1293.6
)
)

PHP add keys to nested arrays

I have nested arrays that do not have keys. I want to add keys in a particular order. What is a clean way to do this?
Start with this array. It is only indexed by position.
[0] => (
[0] => Tyler
[1] => Durden
[2] => 05/07/1985
)
[1] => (
[0] => Edward
[1] => Norton
[2] => 03/21/1988
)
Now apply these keys in order:
['first_name'] =>
['last_name'] =>
['birthday'] =>
Final array:
[0] => (
['first_name'] => Tyler
['last_name'] => Durden
['birthday'] => 05/071985
)
[1] => (
['first_name'] => Edward
['last_name'] => Norton
['birthday'] => 03/21/1988
)
Bonus upvotes if your code allows for any key structure, instead of being hard-coded!
I think array_combine will do the trick:
foreach ($bigarray as &$x) {
$x = array_combine(array('first_name','last_name','birthday'),$x);
}
Also the classic algorythm:
foreach ( $array as $key=>$value ) {
$array[$key]['first_name'] = $array[$key][0];
$array[$key]['last_name'] = $array[$key][1];
$array[$key]['birthday'] = $array[$key][2];
unset($array[$key][0]);
unset($array[$key][1]);
unset($array[$key][2]);
}

Sort a set of arrays based on a single key:value pair in php

Found a question which already explains this - How to sort an array of associative arrays by value of a given key in PHP?
I have an array (A1) of arrays (A2). I would like to sort all A2s inside A1 based on a key:value pair in A2
The structure is like this
A1
->A2-1
->K1:Some Value
->K2:ValB
->A2-2
->K1:Other Value
->K2:ValB1
->A2-3
->K1:Some Value
->K2:ValB2
->A2-4
->K1:Other Value
->K2:ValB3
I would like to sort the arrays in A1 so that all A2s for which K1's value is Other Value are bunched together and all A2s for which K1's value is Some Value are bunched together
So after the sorting, the final order of arrays in A1 should be A2-2, A2-4, A2-1, A2-3. Is there a function in PHP using which I can do this? Or do I have to parse through the entire array and do the sorting?
Thanks.
http://php.net/manual/en/function.array-multisort.php
If that doesn't fit, there's a lot of other array functions http://www.php.net/manual/en/ref.array.php
Have a try with:
$A1 = array(
'A2-1' => array(
'K1' => 'Some Value',
'K2' => 'ValB',
),
'A2-2' => array(
'K1' => 'Other Value',
'K2' => 'ValB1',
),
'A2-3' => array(
'K1' => 'Some Value',
'K2' => 'ValB2',
),
'A2-4' => array(
'K1' => 'Other Value',
'K2' => 'ValB3',
)
);
function mySort($a, $b) {
if ($a['K1'] == $b['K1']) {
return strcmp($a['K2'], $b['K2']);
} else {
return strcmp($a['K1'], $b['K1']);
}
}
uasort($A1, 'mySort');
print_r($A1);
output:
Array
(
[A2-2] => Array
(
[K1] => Other Value
[K2] => ValB1
)
[A2-4] => Array
(
[K1] => Other Value
[K2] => ValB3
)
[A2-1] => Array
(
[K1] => Some Value
[K2] => ValB
)
[A2-3] => Array
(
[K1] => Some Value
[K2] => ValB2
)
)
You need something like:
usort($array, function($a, $b)
{
return strcmp($a['k1'], $b['k1']);
});
You may need to replace strcmp with a different sorting function (or operators) because it's unclear exactly what you are doing.
strategy:
1. find unique values, put them aside.
2. loop through unique values
2.1 loop origial array
2.2 store sub array in $out if unique val = original val
<?php
$i=0;
$a3d = array(
$i++ => array(0=>'Some Value',1=>'ValB'),
$i++ => array(0=>'Other Value',1=>'ValB1'),
$i++ => array(0=>'Some Value',1=>'ValB2'),
$i++ => array(0=>'Zome moar',1=>'ValB4'),
$i++ => array(0=>'Other Value',1=>'ValB3'),
$i++ => array(0=>'Zome Moar',1=>'ValB4'),
);
print_r($a3d);
foreach ($a3d as $a2d){
$uniq[]= $a2d[0];
}
$uniq = array_unique($uniq);
sort($uniq);
print_r($uniq);
foreach ($uniq as $v){
foreach ($a3d as $kk => $a2d){
if ($a2d[0] == $v){
$out[]= $a2d;
unset($a3d[$kk]); // <--avoid rechecking elements
}
}
}
print_r(count($a3d));
print_r($out);
?>
$ php sort_array.php
Array
(
[0] => Array
(
[0] => Some Value
[1] => ValB
)
[1] => Array
(
[0] => Other Value
[1] => ValB1
)
[2] => Array
(
[0] => Some Value
[1] => ValB2
)
[3] => Array
(
[0] => Zome moar
[1] => ValB4
)
[4] => Array
(
[0] => Other Value
[1] => ValB3
)
[5] => Array
(
[0] => Zome Moar
[1] => ValB4
)
)
Array
(
[0] => Other Value
[1] => Some Value
[2] => Zome Moar
[3] => Zome moar
)
0Array
(
[0] => Array
(
[0] => Other Value
[1] => ValB1
)
[1] => Array
(
[0] => Other Value
[1] => ValB3
)
[2] => Array
(
[0] => Some Value
[1] => ValB
)
[3] => Array
(
[0] => Some Value
[1] => ValB2
)
[4] => Array
(
[0] => Zome Moar
[1] => ValB4
)
[5] => Array
(
[0] => Zome moar
[1] => ValB4
)
)

How to sort multiple arrays in PHP

i have wrote a script to produce an array of data but now want to display in order of score. The array outputs as follows;
[display_name] => Array
(
[0] => ACT_Web_Designs
[1] => user1_design
[2] => user2_design
)
[proffesion] => Array
(
[0] => Web Developer
[1] => web developer
[2] => Web Developer
)
[score] => Array
(
[0] => 15
[1] => 6
[2] => 15
)
[img] => Array
(
[0] => ./?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic
[1] =>
[2] =>
)
so in a nutshell I am wanting it to be converted as follows;
[display_name] => Array
(
[0] => ACT_Web_Designs
[1] => user2_design
[2] => user1_design
)
[proffesion] => Array
(
[0] => Web Developer
[1] => web developer
[2] => Web Developer
)
[score] => Array
(
[0] => 15
[1] => 15
[2] => 6
)
[img] => Array
(
[0] => ./?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic
[1] =>
[2] =>
)
I have been looking at asort() but cant get anything to work. any help would be much appreciated.
This is exactly where the PHP's array_multisort comes to use. It is a case where you want to sort many arrays based on the comparison happening in just one of them.
I've modified the array score to have distinct values.
<?php
$arr = array(
'display_name' => array('ACT_Web_Designs','user1_design','user2_design'),
'proffesion' => array('Web Developer','web developer','web developer'),
'score' => array(12,6,15),
'img' => array('./?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic','','')
);
var_dump($arr);
array_multisort($arr['score'], SORT_ASC, SORT_NUMERIC,
$arr['display_name'],
$arr['proffesion'],
$arr['img']
);
var_dump($arr);
?>
Here goes a working demo.
How about this simpler one
$arr = array("k"=>array("A","B","C"),"l"=>array(15,6,15),"n"=>array("k","l","n"));
array_multisort($arr["k"],SORT_NUMERIC,SORT_DESC,$arr["l"],$arr["n"]);
var_dump($arr);
Doesn't it work to just rsort the score array?
rsort($data['score'], SORT_NUMERIC);
I have managed to do this, i was just after a more efficient way;
$array = array(
'display_name' => array(0 => 'ACT_Web_Designs', 1 => 'user1_design', 2 => 'user2_design' ),
'proffesion' => array( 0 => 'Web Developer', 1 => 'web developer', 2 => 'Web Developer' ),
'score' => array( 0 => 15, 1 => 6, 2 => 15 ),
'img' => array( 0 => './?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic', 1 => '', 2 => '' )
);
arsort($array['score'], SORT_NUMERIC );
foreach($array['score'] as $key => $val ) {
$newarray['display_name'][] = $array['display_name'][$key];
$newarray['proffesion'][] = $array['proffesion'][$key];
$newarray['score'][] = $array['score'][$key];
$newarray['img'][] = $array['img'][$key];
}
print_r($newarray);
returns
Array
(
[display_name] => Array
(
[0] => ACT_Web_Designs
[1] => user2_design
[2] => user1_design
)
[proffesion] => Array
(
[0] => Web Developer
[1] => Web Developer
[2] => web developer
)
[score] => Array
(
[0] => 15
[1] => 15
[2] => 6
)
[img] => Array
(
[0] => ./?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic
[1] =>
[2] =>
)
)
Use rsort()
<?php
$fruits = array("lemon", "orange", "banana", "apple");
rsort($fruits);
reset($fruits);
while (list($key, $val) = each($fruits)) {
echo "$key = $val\n";
}
?>
This example would display:
0 = orange
1 = lemon
2 = banana
3 = apple
The most elegant solution that I could find would not reorder the data structure but merely access it in a different fashion.
$scores = $data['score'];
arsort($scores);
$keys_ordered_by_score = array_keys($scores);
Now you can, say, grab the display_name and "proffesion" that has the highest score by the following:
$first_place = $keys_ordered_by_score[0];
echo $data['display_name'][$first_place],
' is a ', $data['proffesion'][$first_place];
Of course, if you really need to reorder the data structure, this idea is useless to you. Any of the other answers using array_multisort() will likely suit that need.
This will not re-sort them for you, but it will let you go through them in the order you want. You can reassign them if you want, but I'd just use this for the output order.
Edit: This will not work, due to the possibility of non-unique key values. See Comments below, and learn from my mistake
$sort_order = $array['score'];
arsort($sort_order);
$sort_order = array_flip($sort_order);
foreach($sort_order as $key){
echo $array['display_name'][$key].' - '.$array['score'][$key];
}

Categories