Array merge if key not exists - php

I tried merging two arrays if the key is not exists in the array but I cannot accomplish this. How can i do? This is what I have tried:
array (size=3) // name of the array $exchange
'purchase' => string '1' (length=1)
'agriculture' => string '1' (length=1)
array (size=6) // name of the array $fixed
'purchase' => string '0' (length=1)
'ICT' => string '0' (length=1)
'agriculture' => string '0' (length=1)
'entertainment' => string '0' (length=1)
'goods and service' => string '0' (length=1)
'other' => string '0' (length=1)
foreach($fixed as $keys=>$values){
if(!in_array($values, $exchange, true)){
array_push($exchange, $keys);
}
}
I get this result:
array (size=7)
'ICT' => string '1' (length=1)
0 => string 'purchase' (length=8)
1 => string 'ICT' (length=3)
2 => string 'agriculture' (length=11)
3 => string 'entertainment' (length=13)
4 => string 'goods and service' (length=17)
5 => string 'other' (length=5)
But I want:
array (size=7)
'ICT' => string '1' (length=1)
'purchase' => string '0' (length=8)
'agriculture' => string '0' (length=11)
'entertainment' => string '0' (length=13)
'goods and service' => string '0' (length=17)
'other' => string '0' (length=5)

Try this:
foreach ($fixed as $keys => $values) {
if (! array_key_exists($keys, $exchange)) {
$exchange[$keys] = $values;
}
}
It checks if the key $keys does not already exists in $exchange and adds it together with its value ($values).
Or you can simply replace the entire foreach() block with:
$exchange = $exchange + $fixed;
The addition $exchange + $fixed adds to $exchange the keys (and their values) that are in $fixed but are not in $exchange. The combined array is then stored in $exchange.
Read also this answer. It explains where your code is wrong.

There's a couple of problems with this:
in_array will search the values of the given array, not the keys, so in this case you just end up checking if the value "0" exists in the array $variable. I assume instead you wanted to check if the key already exists.
array_push pushes a new value into the next available key.
What you need is to check if a key exists, and if not, add it with the existing value. Try this instead:
for($fixed as $key=>$value)
{
if(!isset($exchange[$key])) // Check if the key exists
{
$exchange[$key] = $value; // Add the new key -> value pair.
}
}

Try with array_merge (http://php.net/manual/es/function.array-merge.php)
$result = array_merge($array1, $array2);

You can do it in several ways depending the result you desire:
foreach($fixed as $key=>$values){
if(!isset($exchange[$key])){
$exchange[$key]=values;
}
}
or
$exchange += $fixed;
or
$exchange = array_merge($fixed,$exchange);

Related

How to echo special value from key in array/json structure

I can easly explore json for example:
foreach($json_a['somwhere'][1]['somwhere_deeper'] as $something){
var_dump($something);
}
This code makes me print something like this:
C:\wamp64\www\dothejob.php:7:
array (size=2)
'name' => string 'John' (length=17)
'value' => string '15' (length=4)
C:\wamp64\www\dothejob.php:7:
array (size=2)
'name' => string 'Joanna' (length=6)
'value' => string '23' (length=2)
C:\wamp64\www\dothejob.php:7:
array (size=2)
'name' => string 'John' (length=17)
'value' => string '55' (length=10)
C:\wamp64\www\dothejob.php:7:
array (size=2)
'name' => string 'Joanna' (length=11)
'value' => string '55' (length=5)
So I'm sure I'm in a right place, but now the question is how to print only value which is in array, where name is Joanna?
I know it should be easy If statement, but I'm not sure how those keys/values works, Its easy question, but I'm beginner with php... :) ps. I was looking for help but didn't found solution yet.
Can't use $something[n], because they are not allways on the same "place", so only right solution is something like this:
I'm looking for something like this:
if 'name' is 'Joanna':
print value of 'value'
You can use $something[n] because you have an associative array :
foreach($json_a['somwhere'][1]['somwhere_deeper'] as $something){
if ($something['name'] == 'Joanna') {
var_dump($something);
}
}
Output should be :
C:\wamp64\www\dothejob.php:7:
array (size=2)
'name' => string 'Joanna' (length=6)
'value' => string '23' (length=2)
C:\wamp64\www\dothejob.php:7:
array (size=2)
'name' => string 'Joanna' (length=11)
'value' => string '55' (length=5)
Of course, if you want to var_dump the value only, use var_dump($something['value']).
you need to update naming convension of Variable
foreach($json_a['somwhere'][1]['somwhere_deeper'] as $key => $value){
echo $key." : ".$value
}
Output of above code will be something like
John : 15
Johnna : 23
foreach(array as key => value)
{
//key represent array key
//value represent value of that array
}
Let me know in case of any concern.

How to loop over an array and conditionally update a nested value

I have two arrays like:
array (size=4)
0 => string '5' (length=1)
1 => string '4' (length=1)
2 => string '2' (length=1)
3 => string '2' (length=1)
3 => string '8' (length=1)
and one array more that I load from an XML file:
object(SimpleXMLElement)[1]
public 'book' =>
array (size=101)
0 =>
object(SimpleXMLElement)[2]
public 'id' => string '1' (length=1)
public 'title' => string 'p' (length=1)
1 =>
object(SimpleXMLElement)[3]
public 'id' => string '2' (length=1)
public 'title' => string 'pp' (length=2)
2 =>
object(SimpleXMLElement)[4]
public 'id' => string '3' (length=1)
public 'title' => string 'pen' (length=3)
3 =>
object(SimpleXMLElement)[5]
public 'id' => string '4' (length=1)
public 'title' => string 'lapton' (length=6)
......
......
101 =>
object(SimpleXMLElement)[103]
public 'id' => string '101' (length=1)
public 'title' => string 'title' (length=5)
I want to compare each value of key id of second array with key of first array for each value. When it's the same, I want to update value of key title of second array.
Assuming your first array is $idArray and your second is $xmlArray, you could use something like this.
$result = array_map(function($xmlElement) use ($idArray) {
if (in_array($xmlElement->id, $idArray)) {
$xmlElement->title = 'updated value';
}
return $xmlElement;
}, $xmlArray);
Assumptions
the first array is called $array1
the second array is called $fromXML
the second array is not actually an array, it's a SimpleXMLElement with the following structure (psuedocode / JSONish syntax)
{
'book' => {
0 => SimpleXMLElement {
'id' => 1,
'title' => 'p'
}
}
}
I assume you can access the second array of elements with $fromXML['book']
I assume you can access an attribute of the first element with $fromXML['book'][0]['id']
I assume that you can set the text of the title of the first element with $fromXML['book'][0]['title'][0] = 'new title'
based on How can I set text value of SimpleXmlElement without using its parent? and PHP SimpleXML, how to set attributes? and PHP foreach change original array values
Solution
foreach($fromXML['book'] as $key => $element) {
if(array_key_exists($element['id'], $array1)) {
$fromXML['book'][$key]['title'][0] = $array1[$element->id];
}
}
Caveat and troubleshooting
I didn't test this, just going off of the documentation. If I've misinterpreted the structure of your SimpleXMLElement array, try experimenting with var_dump($fromXML['some']['key']) until you find the right way to access the array/element
Note: Apparently, array_key_exists() performs better than in_array() on large arrays
Try this for now
foreach($array1 as $arr1 => $val1){
foreach($array2 as $arr2 =>$val2){
if($arr1==$arr2){
$val2['title']='update value';
}
}
}

Php Array sorting assoc key after intersect key

Currently I have this:
$pattern = array('industry_id','category_id','subcategory_id');
$data = array('advert_id' => string '261501' (length=6)
'advert_type_id' => string '7' (length=1)
'user_id' => string '6221' (length=4)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
'model' => string 'Custom Semi Drop Deck Trailer' (length=29)
'description' => string 'Industry: Trailer );
Then:
array_intersect_key( $data , array_flip($pattern) );
Using array_interect_key & array_flip to get the values from $data based on $pattern, I will get a result like this:
array (size=3)
'category_id' => string '769' (length=3)
'subcategory_id' => string '930' (length=3)
'industry_id' => string '17' (length=2)
Unfortunately as you can see the result key sorting is not the same that I declared in $pattern. Is there a shorthand way to sort it like I declared in $pattern because after this I want to implode the array and do something like this industry_id.category_id.subcategory_id without hard coding the keys.
Since you already figured out array_intersect_key method which will not get you the desired key ordering of $pattern, try this instead:
// since original $pattern is not ASSOC (only vals)
// flip it so defined vals become keys
$pattern_flipped = array_flip($pattern);
$result = array();
foreach ($pattern_flipped as $k => $v) {
if (isset($data[$k])) {
$result[$k] = $data[$k];
}
}
var_dump($result); // test
// can use original 0 1 2 dynamic keys for concatenation
echo $result[$pattern[0]], $result[$pattern[1]], $result[$pattern[2]], '<br>';
// or use hardcoded keys
echo $result['industry_id'], $result['category_id'], $result['subcategory_id'], '<br>';
You know I'm not sure how you're getting the result you describe. I've tried your code and I get
array (size=3)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
You could do this another way though using array_filter
$newData = array_filter($data, function($key) use ($pattern) {
if (in_array($key, $pattern))
return true;
}, ARRAY_FILTER_USE_KEY)

SQL/PHP sort fields from a form to make insert

I've got a form which users can add new rows by clicking on a button and automatically, it adds +1 on the field's name.
So for example, I've got my train_id_1, train_type_1 and my user wants to add a new one, so now I've got train_id_2 and train_type_2.
In order to save this in my database, I would like to sort and seperate train_type_1 / train_type_2... to make a foreach and then to save in my database.
So, the var_dump of my $_POST looks like :
array (size=60)
'train_id_1' => string ' 07:36' (length=6)
'train_type_1' => string ' -Z' (length=3)
'user_id_1' => string 'CPN' (length=3)
'event_criter_1' =>
array (size=3)
0 => string 'test' (length=4)
1 => string '234' (length=3)
2 => string '532' (length=3)
'train_id_2' => string ' 08:32' (length=6)
'train_type_2' => string ' -X' (length=3)
'user_id_2' => string 'CPN' (length=3)
'event_criter_2' =>
array (size=3)
0 => string 'TESTG' (length=5)
1 => string 'GGG' (length=3)
2 => string 'AETG' (length=4)
'train_id_3' => string ' 08:36' (length=6)
'train_type_3' => string ' -Z' (length=3)
'user_id_3' => string 'CPN' (length=3)
'event_criter_3' =>
array (size=1)
0 => string '' (length=0)
'train_id_4' => string ' 09:04' (length=6)
'train_type_4' => string ' -X' (length=3)
'user_id_4' => string 'CPN' (length=3)
'event_criter_4' =>
array (size=1)
0 => string '' (length=0)
Do you know how I can make abcd_1 separate from abcd_2 to make my foreach (or another solution) ?
Thank you!
Loop through your array, matching _1 and insert the posted elements as one row. Then increment and match _2 etc..
$postedElements = $_POST;
$elementsPerRow = 4;
$numRows = count($postedElements)/$elementsPerRow;
// loop through the number of 'rows' to insert
for($i=1;$i<=$numRows;$i++){
// Build an array to store matched elements to insert
$elementsToInsert = array();
//process the complete _POST array each time...
foreach($postedElements as $name => $value){
// ...get the 'row' (the bit after the underscore)...
//list($value,$row) = explode('_',$name); // doesn't work for 2 underscores..
$row = end(explode($name)); // This will
if($row == $i){
// ...and add elements that match to an insert array
// $elementsToInsert[] = $name;
$elementsToInsert[$name] = $value;
}
}
// insert $elementsToInsert into DB
}
I think, at first You need to have a amount of records in array through count($arr). Then use usual for loop:
//output of field names
for ($i = 0; $i < count($arr); $i++){
//Work with array
}
Make a new array.
Then add a data from loop into new array.
I think it could help You.
And by which reason You need to sort them?

multiarray - how to keep first 3 index groups of each source type

I have a multi-array where I need to keep the first 3 index groups and remove the rest from the multiarray (in each group).
See multiarray here: https://gist.github.com/no1uknow/6887497
So:
In this example I need the multi-array to keep: The first 3 Heavy, Lite, Intermediate, etc (these are identified by the source_type_cd)
Example of the Lite part of the array after the first 3 are kept:
0 =>
array (size=9)
'validated_ata' => string '25' (length=2)
'source_type_cd' => string 'Lite' (length=4)
'validated_subata' => string '22' (length=2)
'action_cd' => string '3' (length=1)
'object_cd' => string '5' (length=1)
'malfunction_cd' => string '29' (length=2)
'corrective_action_txt' => string 'Repair-Passenger Seat-Loose / Displaced' (length=39)
'rec_count' => string '00050' (length=5)
'group_id' => int 48
1 =>
array (size=9)
'validated_ata' => string '25' (length=2)
'source_type_cd' => string 'Lite' (length=4)
'validated_subata' => string '22' (length=2)
'action_cd' => string '3' (length=1)
'object_cd' => string '5' (length=1)
'malfunction_cd' => string '1' (length=1)
'corrective_action_txt' => string 'Repair-Passenger Seat-Inoperative' (length=33)
'rec_count' => string '00047' (length=5)
'group_id' => int 44
2 =>
array (size=9)
'validated_ata' => string '25' (length=2)
'source_type_cd' => string 'Lite' (length=4)
'validated_subata' => string '22' (length=2)
'action_cd' => string '3' (length=1)
'object_cd' => string '5' (length=1)
'malfunction_cd' => string '31' (length=2)
'corrective_action_txt' => string 'Repair-Passenger Seat-Worn / Chaffed / Frayed' (length=45)
'rec_count' => string '00042' (length=5)
'group_id' => int 50
You will simply have to loop through the array and look if it has any of those values and place into a new array.
Example (where $arr is your multiarray):
// My silly solution for knowing what to look for
// When one is found, it will be removed from the array.
$find = array('Lite','Lite','Lite','Intermediate','Intermediate','Intermediate','Heavy','Heavy','Heavy');
// New array where your the values you want will be placed in
$new_arr = array();
foreach($arr as $v) {
// No need to keep looking if there's no more to find.
if(empty($find))
break;
// Look in $find array if current "source_type_cd" is still sought-after
$key = array_search($v['source_type_cd'], $find);
if($key !== false) {
$new_arr[] = $v; // Add to new array
unset($find[$key]); // Remove from "find" array
}
}
Thanks Colandus I actually figured it out like this... I was trying to avoid to many loops.
In a loop above this I set the source_type_cd in an array:
$groups[]=$value['source_type_cd']
Next I loop through the array and take the top 3 of each group by using array_splice twice and then merging back into a new array.
(also, I'm using a start and end point ($group_count).)
$start = 0;
$group_count = $i+1;
$top_count = 3;
foreach($groups as $k => $v) {
$top_count_array = array_merge((array)$top_count_array, (array)array_slice(array_slice($sorted_array, $start, $group_count, true),0,$top_count,true));
$start = $start+$group_count;
}
var_dump($top_count_array);
Again appreciate the input. Tried to shorten this code down from so many loops. Also requirements will change for grabbing the amount of $top_count and $group_count... Needed something a little more dynamic. :-)

Categories