Php replace array keys with another array keys if key exists - php

I have this array :
Array (amounts)
(
[0] => Array
(
[0] => 95
[1] => 2
)
[1] => Array
(
[0] => 96
[1] => 5
)
)
And this
Array (invoices)
(
[1] =>
[2] => 490
[3] =>
[4] =>
[5] => 1400
)
This is what I am trying to get :
Array
(
[1] =>
[95] => 490 // Id found in Amounts array so replaced id by Key '0'
[3] =>
[4] =>
[96] => 1400 // Id found in Amounts array so replaced id by Key '0'
)
I have tried to deal with the answser found here but without success.
$newamounts = array_combine(array_map(function($key) use ($invoices) {
return $invoices[$key]; // translate key to name
}, array_keys($invoices)), $amounts);
Any help greatly appreciated. Thx

This should work for you:
(Here i go through each innerArray of $amounts with a foreach loop and then i check if the array element in $invoices with the index 1 of the innerArray is not empty and if not i set the new element with the key and value and unset the old one)
<?php
$amounts = array(
array(
95,
2
),
array(
96,
5
)
);
$invoices = array(1 =>"", 2 => 490, 3 => "", 4 => "", 5 => 1500);
foreach($amounts as $innerArray) {
if(!empty($invoices[$innerArray[1]])) {
$invoices[$innerArray[0]] = $invoices[$innerArray[1]];
unset($invoices[$innerArray[1]]);
}
}
print_r($invoices);
?>
Output:
Array ( [1] => [3] => [4] => [95] => 490 [96] => 1500 )

Related

Sync array values across all related array keys

I have a PHP array with the following data
Array
(
[3] => Array
(
[0] => 4095
[2] => 651
)
[4095] => Array
(
[0] => 3
)
[651] => Array
(
[0] => 4432
)
[4432] => Array
(
[0] => 651
)
[92] => Array
(
[0] => 45
)
)
The above array has keys as student_id and the values are also student_id creating a circular relation. What I am trying to achieve is all the student_id has the same set of student_id values. Basically if student_id 3 is related to 4095, 4432 & 651, then, in turn, each of these values has to have 3 among them including other student_id from 3. The below output demonstrates what I am trying to achieve.
Array
(
[3] => Array
(
[0] => 4095
[1] => 4432
[2] => 651
)
[4095] => Array
(
[0] => 3
[1] => 4432
[2] => 651
)
[651] => Array
(
[0] => 3
[1] => 4432
[2] => 4095
)
[4432] => Array
(
[0] => 3
[1] => 4095
[2] => 651
)
[92] => Array
(
[0] => 45
)
[45] => Array
(
[0] => 92
)
)
Explanation of output
The array keys 3, 4095, 651 & 4432 are related to each other either directly or via a common relation (indirect), so will have common set of values (siblings). The key 92 in input array has a value (sibling) of 45, so in a resultant array, a new key 45 will be added to array with the inverse relation as well.
What I have tried so far
I have tried to do it with this code
$syncedSiblings = [];
foreach ($studentsWithSiblings as $sid => $siblings) {
$all = map_assoc(array_merge([$sid], array_keys($siblings)));
foreach ($all as $studentId) {
if (isset($syncedSiblings[$studentId])) {
$old = $syncedSiblings[$studentId];
$syncedSiblings[$studentId] = array_unique(array_merge($old, array_except($all, $studentId)));
} else {
$syncedSiblings[$studentId] = array_unique(array_except($all, $studentId));
}
}
}
Where $studentsWithSiblings has the above array & array_except returns array without the passed values as second argument.
This is the output I am getting right now
Array
(
[3] => Array
(
[0] => 4095
[1] => 651
)
[4095] => Array
(
[0] => 3
[1] => 651
)
[651] => Array
(
[0] => 3
[1] => 4095
[2] => 4432
)
[4432] => Array
(
[0] => 651
)
[92] => Array
(
[0] => 45
)
)
Any help with this will be highly appreciated.
If I've understood you correctly, then this possible to achieve with recursion:
function getChildren($ind_ar, $prev_ar, $data, $rem){
$tmp = [];
$mark = 0;
foreach($ind_ar as $ind){
foreach($data[$ind] as $new_val){
if(!in_array($new_val,$prev_ar) && $new_val != $ind && $new_val != $rem){
$mark = 1;
$tmp[] = $new_val;
}
foreach($data[$new_val] as $new){
if(!in_array($new,$prev_ar) && $new != $ind && $new != $rem){
$mark = 1;
$tmp[] = $new;
}
}
}
}
$res_ar = $prev_ar;
if(!empty($tmp)) $res_ar = array_unique(array_merge($tmp,$prev_ar));
if($mark) $res_ar = getChildren($tmp,$res_ar,$data, $rem);
return $res_ar;
}
You can use this function in this way:
$data = array( 3 => [4095, 651], 4095 => [3], 651 => [4432], 4432 => [3, 651], 92 => [45], 45 => [92], );
foreach($data as $in => &$data_val) {
$data_val = getChildren([$in],$data_val,$data, $in);
sort($data_val);
}
Demo
Output:
Array
(
[3] => Array
(
[0] => 651
[1] => 4095
[2] => 4432
)
[4095] => Array
(
[0] => 3
[1] => 651
[2] => 4432
)
[651] => Array
(
[0] => 3
[1] => 4095
[2] => 4432
)
[4432] => Array
(
[0] => 3
[1] => 651
[2] => 4095
)
[92] => Array
(
[0] => 45
)
[45] => Array
(
[0] => 92
)
)
Two nested loops over the data. If the keys are different, then check if the key of the inner loop is already contained in the data array of the outer key element - if not, add it.
$data = json_decode('{"3":{"0":4095,"2":651},"4095":[3],"651":[4432],"4432":{"1":651}}', true);
foreach($data as $key_outer => $val_outer) {
foreach($data as $key_inner => $val_inner) {
if($key_outer != $key_inner && !in_array($key_inner, $data[$key_outer])) {
$data[$key_outer][] = $key_inner;
}
}
}
var_dump($data);
This gets you
array (size=4)
3 =>
array (size=3)
0 => int 4095
2 => int 651
3 => int 4432
4095 =>
array (size=3)
0 => int 3
1 => int 651
2 => int 4432
651 =>
array (size=3)
0 => int 4432
1 => int 3
2 => int 4095
4432 =>
array (size=3)
1 => int 651
2 => int 3
3 => int 4095
I am assuming a specific order of the elements in those sub-items is not actually required. If it is, then please sort them yourself as desired afterwards or in between (depending on what exactly you need, f.e. sort($data[$key_outer]); after the inner loop would get you the IDs in all sub-arrays sorted ascending.)

add items to multidimensional array programmatically in php

I have the following array
$a = array(0 => 'Item',
1 => 'Wattles',
2 => 'Types',
3 => 'Compost',
4=> 'Estimated',
5 => '123',
6 => 'Actual',
7 => '12',
);
That is sorted with the following code.
echo "<pre>";
print_r($a);
$a_len = count($a);
$fnl = array();
$i = 0;
while($i<$a_len){
$fnl[$a[$i]] = $a[++$i];
$i++;
}
print_r($fnl);
It prints correctly
Array
(
[Item] => Wattles
[Types] => Compost
[Estimated Qty] => 123
[Actual Qty] => 12
)
until i add multiple entries.
Array
(
[0] => Item
[1] => Wattles
[2] => Types
[3] => Compost
[4] => Estimated Qty
[5] => 123
[6] => Actual Qty
[7] => 12
[8] => Item
[9] => Silt Fence
[10] => Types
[11] => Straw
[12] => Estimated Qty
[13] => 45
[14] => Actual Qty
[15] => 142
)
I need to make this add items in a multidimensional array.
$items = array
(
array("Wattles","Silt Fence), //items
array("Compost","Straw"), //types
array(123,45), //estimated quantity
array(12,142) //actual quantity
);
There are a few given numbers. There are exactly 4 entries (8 items) before the list repeats itself.
I have been stuck on this portion for hours, and don't know how to get my code working as I want it to.
To get the expected result with string keys you can do:
foreach(array_chunk($a, 2) as $pairs) {
$result[$pairs[0]][] = $pairs[1];
}
Yields:
Array
(
[Item] => Array
(
[0] => Wattles
[1] => Silt Fence
)
[Types] => Array
(
[0] => Compost
[1] => Straw
)
[Estimated] => Array
(
[0] => 123
[1] => 45
)
[Actual] => Array
(
[0] => 12
[1] => 142
)
)
Then if you want it numerically indexed:
$result = array_values($result);
You have your structure for a multidimensional array wrong. You should construct your array like this:
$a = array(
0 => array(
'Item' => 'Wattles',
'Types' => 'Compost',
'Estimated' => 123,
'Actual' => 12
)
);
Then to add to it:
$a[] = array(
'Item' => 'Silt Fence',
'Types' => 'Straw',
'Estimated' => 45,
'Actual' => 142
);
Render it out to see the results which are what I think you are looking for.
print_r($a);
I can post a link if you want to learn how to sort multidimensional arrays by sub-array values if you need.

Rearrange array values according to another array values in php

I have got 2 arrays(One single and one multidimensional).
Single array "A" looks like
[questionid] => Array
(
[0] => 12
[1] => 13
[2] => 55
[3] => 15
[4] => 16
)
Multidimensional array "B" looks like
Array
(
[0] => Array
(
[quid] => 12
[answer] => AAA
)
[1] => Array
(
[quid] => 13
[answer] => neighbour
)
[2] => Array
(
[quid] => 15
[answer] =>
)
[3] => Array
(
[quid] => 16
[answer] =>
)
[4] => Array
(
[quid] => 55
[answer] =>
)
)
Now I want the array B (quid) values to be rearranged depending upon the values from array A. So in array B the value of quid last element(55) is at the very end whereas in array A it is in 3rd position.
I want the array B look like this
Array
(
[0] => Array
(
[quid] => 12
[answer] => AAA
)
[1] => Array
(
[quid] => 13
[answer] => neighbour
)
[2] => Array
(
[quid] => 55
[answer] =>
)
[3] => Array
(
[quid] => 15
[answer] =>
)
[4] => Array
(
[quid] => 16
[answer] =>
)
)
The code for multidimensional array is
$ansid = array
(
array
(
"quid" => 12,
"answer" => "AAA"
),
array
(
"quid" => 13,
"answer" => "neighbour"
),
array
(
"quid" => 15,
"answer" =>""
),
array
(
"quid" => 16,
"answer" =>""
),
array
(
"quid" => 55,
"answer" =>""
)
);
Not using array_walk() as to be mor demonstrative, you could just
$newB=array()
foreach ($arrayB as $b) $newB[$b['quid']]=$b;
$newA=array()
foreach ($arrayA as $k=>$v) $newA[$k]=$newB[$v]
//$newA has the required structure
With the user sort function:
$single_array = ...; // order by the index of this array
$mult_dim_array = ...; // to be ordered by the 'quid' value of the elements
function my_comp($a, $b) {
return array_search($a['quid'], $single_array ) - array_search($b['quid'], $single_array );
}
usort($mult_dim_array, "my_comp");
This will get the index on your first array to determine which element goes first or later. The function reads $single_array as a global variable (defined outside the function).
Documentation at http://php.net/manual/en/function.usort.php

Taking Value from one array with keys aret the valuses of another another array in php

I have one array called $stocknumb
$stocknumb= Array ( [0] => 102 [1] => 103 [2] => 104 )
Another array called $price it contains both $stocknumb as well as price
$price=Array ( ['102'] => Array ( [0] => 2000 ) ['103'] => Array ( [0] => 3 ) ['104'] => Array ( [0] => 4000 ) )
Now i would like to get prices for only stock numbers which are in $stocknumb array. Both price and stock number are in $price array.
How to get it in PHP.
See array_column function (php >= 5.5) :
$price= array(
102 => array(0 => 2000),
103 => array(0 => 3),
104 => array(0 => 4000)
);
$array_price = array_column ($price, 0);
print_r($array_price);
/*Array
(
[0] => 2000
[1] => 3
[2] => 4000
)
*/
If you don't use php 5.5, see :
https://github.com/ramsey/array_column/blob/master/src/array_column.php
If you want final data as array then with conventional way of looping could be done as
$stocknumb= Array ( 0 => 102, 1 => 103, 2 => 104 ) ;
$price=Array ( '102' => Array ( 0 => 2000 ), '103' => Array ( 0 => 3 ), '104' => Array ( 0 => 4000 ) );
$final_array = array() ;
foreach($stocknumb as $key=>$val){
if(array_key_exists($val,$price)){
$final_array[$val] = $price[$val][0];
}
}
print_r($final_array);
Output
Array ( [102] => 2000 [103] => 3 [104] => 4000 )
You can use array intersect function
$stocknumb= array ( 102, 103 );
// Make the key same as the value.
$stocknumb = array_combine($stocknumb, $stocknumb);
$price= array (102 => array (2000), 103 => array (3), 104 => array (4000 ));
$filtered = array_intersect_key($price, $stocknumb);
A single line of code with array_flip() and array_key_intersect() will suffice
$new_arr=array_intersect_key($price, array_flip($stocknumb));
OUTPUT :
Array
(
[102] => Array
(
[0] => 2000
)
[103] => Array
(
[0] => 3
)
[104] => Array
(
[0] => 4000
)
)
<?php
foreach($price as $key => $value) {
if(in_array($key, $stocknumb)) {
echo $value[0];
}
}
DEMO

Check values of sub-arrays, use key as new value in new array - PHP

I have an array, let call it $mainArray, which looks like this: -
Array
(
[1] => Array
(
)
[5] => Array
(
[0] => 10
[1] => 15
[2] => 20
[3] => 25
)
[80] => Array
(
[0] => 20
[1] => 40
[2] => 50
[3] => 60
)
[777] => Array
(
[0] => 100
[1] => 200
[2] => 300
[3] => 400
)
[666] => Array
(
[0] => 1234
[1] => 5678
[2] => 20
[3] => 9865
)
[555] => Array
(
[0] => 111
[1] => 222
[2] => 333
[3] => 444
)
)
What I want to do is create 2 new arrays: -
1) Where values are equal to the key names of $mainArray, but only those where the sub-array (if there is one) contains the value "20" somewhere in it. For example my new array (call it $arrayOne) will be [0] => 5, [1] => 80, [2] => 666.
2) Similar to above, but where there's either no sub-array or, if there is, it doesn't include "20" as a value. So that (call it $arrayTwo) would be [0] => 1, [1] => 777, [2] =>555.
I've tried loads of for each loops and even a little RecursiveIteratorIterator (whatever that is!) but can't seem to reference keys and values in the way that I need to. Any help would be much appreciated!
Will this do?:
<?php
foreach( $mainArray as $mKey => &$mVal )
{
if( in_array( 20, $mVal ) )
{
$arrayOne[] = $mKey;
}
else
{
$arrayTwo[] = $mKey;
}
}
I trust you can create a function which would check if array contains 20 as it's value or not. Let's call this function has20.
You two new arrays would then be array_filter($mainArray, 'has20') and array_filter($mainArray, function ($x) {return !has20($x);})
You can do it like this:
$newArray = array();
foreach($mainArray as $key => $subArray) {
if (in_array(20, $subArray)) {
$newArray[] = $key;
}
}

Categories