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';
}
}
}
Related
I have a parent array called $list, and when I var_dump($list); this is the result:
array (size=10)
0 =>
array (size=4)
'id' => string '6' (length=1)
'title' => string 'Title #1' (length=7)
1 =>
array (size=4)
'id' => string '10' (length=2)
'title' => string 'Title x' (length=7)
...
9 =>
array (size=4)
'id' => string '2' (length=1)
'title' => string 'Title y' (length=3)
As you see i have two keys 'id' and 'title'.
I want to add another multidimensional array as an third key named 'children'
I am able to get data of 'children' with my function named GetChildrenById($id);
But i don't know how to add this array as a third key and name the key 'children'
*
I tried to reach every children by foreach loop but i need result as a big array.
How to achieve this?
You probably need that:
foreach ($list as &$v) {
$v['children'] = GetChildrenById($v['id']);
}
The & before $v indicates that $v is a reference to a $list item and not a copy. Consequence, when you apply a change to $v, the $list item is modified.
But you can also use the array indexes like that:
foreach ($list as $k => $v) {
$list[$k]['children'] = GetChildrenById($v['id']);
}
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)
my problem is that I'm sending html form data via jquery here's the code :
$('#search_button').click(function(event) {
var track_load = 0; //total loaded record group(s)
var loading = false; //to prevents multipal ajax loads
var total_groups = <?php echo $total_groups; ?>; //total record group(s)
var Data = $("#srch_form").serializeArray();
console.log(Data);
$('#results').load("autoload_process.php", {
data:Data,
'group_no':track_load},
function() {track_load++;}); //load first group
});
and in the php receiving page I'm getting an array with one array per name&value pair inside like this :
array (size=4)
0 =>
array (size=2)
'name' => string 'srch_word' (length=9)
'value' => string '' (length=0)
1 =>
array (size=2)
'name' => string 'srch_cat-2' (length=10)
'value' => string '2' (length=1)
2 =>
array (size=2)
'name' => string 'srch_cat-5' (length=10)
'value' => string '5' (length=1)
3 =>
array (size=2)
'name' => string 'srch_cat-6' (length=10)
'value' => string '6' (length=1)
But before with html only form post I was getting one array with the pairs inside :
array (size=4)
'srch_word' => string '' (length=0)
'srch_cat-2' => string '2' (length=1)
'srch_cat-5' => string '5' (length=1)
'srch_cat-6' => string '6' (length=1)
And I use to access the values like an associative array would do ($_POST['srch_word'], or even just $srch_word would work ), now I can't do that.
¿How can I get one array from the jquery post or how can I reduce this array of arrays to one array in the php file or what should I do in this case?
I would appreciate your help.
this is sample maybe usefull for you as long number of child array always two
<?php
$keys = array();
$value = array();
$serialize = array(array('name' => 'srch_word', 'value' => ''), array('name' => 'srch_cat-2', 'value' => '2'));
foreach ($serialize as $key) {
array_push($keys, $key['name']);
array_push($value, $key['value']);
}
$final = array_combine($keys, $value);
echo '<pre>',print_r($final),'</pre>';
?>
replace $serialize as your array define
please vote if you like it
I am trying to parse out certain things within the JSON code, but the problem is that the two groups of arrays that have the information in it I need have random names, here is from the var_dump:
array (size=2)
'results' =>
array (size=1)
0 => string 'Phone.5d5b6fef-a2e0-4b08-cfe3-bc7128b776c3.Durable' (length=50)
'dictionary' =>
array (size=3)
'Person.51f28c76-2993-42d3-8d65-4ea0a66c5e16.Ephemeral' =>
array (size=8)
'id' =>
array (size=5)
...
'type' => null
'names' =>
array (size=1)
...
'age_range' => null
'locations' => null
'phones' =>
array (size=1)
...
'best_name' => string 'John Smith' (length=15)
'best_location' => null
'Location.28dc9041-a0ee-4613-a3b0-65839aa461da.Durable' =>
array (size=30)
'id' =>
array (size=5)
...
'type' => string 'ZipPlus4' (length=8)
'valid_for' => null
'legal_entities_at' => null
'city' => string 'City' (length=8)
'postal_code' => string '12345' (length=5)
'zip4' => string '4812' (length=4)
'state_code' => string 'MO' (length=2)
'country_code' => string 'US' (length=2)
'address' => string 'Main St, City, MO 12345-4812' (length=33)
'house' => null
No I am trying to get best_name from under the part that starts with Person and address under Location. But when I do:
$string = file_get_contents($url);
$json=json_decode($string,true);
var_dump($json);
echo $json['dictionary']['Person']['best_name'];
I get Undefined index: Person error, because the actual object name for Person is:
Person.51f28c76-2993-42d3-8d65-4ea0a66c5e16.Ephemeral which is different every time I do a search. Is there a way to do this without putting the random generated line in?
Hopefully this makes sense, thanks for the help in advance!
If the Person key always starts with the string "Person", than simply do a foreach and check the key which contains this string.
Like:
foreach ($json['dictionary'] as $key => $value) {
if (preg_match('/^Person/', $key)) {
echo $json['dictionary'][$key]['best_name'];
}
}
Of course this get complicated, if you have multiple keys which start with "Person".
You can do the same with "Location" or any other string you need.
How about something like this ... loop through $json['dictionary']'s index keys to find something that starts with "Person".
$foundIt = false;
foreach (array_keys($json['dictionary']) as $key) {
if (substr($key,0,6) == 'Person') {
$foundIt = $key;
break;
}
}
if ($foundIt) { echo $json['dictionary'][$foundIt]['best_name']; }
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. :-)