I do not know what is wrong with my php code. I want to have an Associative Array in the format. When I run my code I get this data. [KY] is an array in the [OH] array.
Array ( [Oh] => Array ( [state] => Oh ) [income] => 100 [count] => 1 [Ky] => Array ( [state] => Ky ) )
Array (
[OH] => Array
( [income] =>
[count] =>
)
[KY] => Array
( [income] =>
[count] =>
)
Here is my code
Example data in $array
Array ( [0] => Array (
[SurveyDate] => 1952-06-21
[Income] => 100
[CountyState] => Hamilton|Oh
[count] => 1 ) )
function update_array_value3( $array )
{
foreach ($array as $row)
{
$arrCountyState = explode( "|", $row['CountyState'] );
$key = $arrCountyState[1]; // OH or KY
if( !isset( $_SESSION['sIncome'][$key] ) )
{
$_SESSION['sIncome'][$key]['state'] = $key;
$_SESSION['sIncome'][$key]['income'] = $row['Income'];
$_SESSION['sIncome'][$key]['count'] = 1;
} else
{
$_SESSION['sIncome'][$key]['state'] = $key;
$_SESSION['sIncome'][$key]['income'] += $row['Income'];
$_SESSION['sIncome'][$key]['count'] += 1;
}
}
I can't tell you the root cause of the problem simply based on this snippet of code, but it seems $row either doesn't contain the data you expect it to, or doesn't contain any data.
In your code you reference $row['CountyState'], yet I don't see any array item called CountyState in $array.
Also, I'm not sure whether or not this is intentional, but in your foreach() loop it looks like $_SESSION['sIncome']['income'] and $_SESSION['sIncome']['count'] are being overwritten. Each time the loop encounters a new $key, it will overwrite those values.
Related
My array looks like this, please note that I am free to change my array structure, if you think another format is more flexible:
Array (
[import_data] => Array (
[mods] => Array (
[values] => Array (
[mod_1_key] => Array (
[value] => http://127.0.0.1/wordpress/wp-content/uploads/2019/11/hacking-voice-controllable-devices-with-laser-26.jpg
[status] => new
)
[mod_2_key] => Array (
[value] => mod_2_value
[status] => new
)
[mod_3_key] => Array (
[value] => mod_3_value
[status] => new
)
)
[new] => Array (
[0] => mod_1_key
[1] => mod_2_key
[2] => mod_3_key
)
)
[options] => Array (
[values] => Array (
[option_1_key] => Array (
[value] => option_1_value
[status] => new
)
[option_2_key] => Array (
[value] => option_2_value
[status] => new
)
[option_3_key] => Array (
[value] => option_3_value
[status] => new
)
)
[new] => Array (
[0] => option_1_key
[1] => option_2_key
[2] => option_3_key
)
)
)
)
I'm trying to loop through multiple keys within the array, but only for a total on N times, shared amongst these loops. My actual, current code is:
if( array_key_exists( 'new', $package['options'] ) ) {
foreach( $package['new'] as $new_option_key ) {
//do something with it.
}
}
if( array_key_exists( 'changed', $package['options'] ) ) {
foreach( $package['changed'] as $changed_option_key ) {
//do something with it.
}
}
So, I would want to perform these operations for the keys new and changed only for these N times. That is to say, if my N is 6, then each loop should only run 3 times.
If I were to introduce a $run_counter and increase it every time I loop, then check it in the loop every time, it works - I tried it, but the code looks like total garbage. As such my question is not only about how can I do something, but how can I do it gracefully?
Since you are looking for a clean and nice looking code I would suggest trying
foreach(array_slice($package["new"], 0, $N / 2, TRUE) as $key)
....
foreach(array_slice($package["changed"], 0, $N / 2, TRUE) as $key)
....
PHP uses copy-on-write technique so the array that is being returned by array_slice() will internally contain just references to the original values in the original array (do not mix these "internal references" with the real &$x variable references).
Why not just use a regular for loop then?
$max_iteration = 3;
if( array_key_exists( 'new', $package['options'] ) ) {
for($i = 0; $i < $max_iteration; $i++) {
$new = $package['new'][$i];
//do something with it.
}
}
if( array_key_exists( 'changed', $package['options'] ) ) {
for($i = 0; $i < $max_iteration; $i++) {
$changed = $package['changed'][$i];
//do something with it.
}
}
I am using an API and am using a few foreach loops to get to the stage that I am at right now. Please see code below with my comments and also the results that I am getting below that.
// get recent_games api data
$recent_games_data = $player->recent_games();
//start arrays for below
$matches = array();
$gameType = array();
$myData = array();
// using foreach loops to dig in to api data
foreach($recent_games_data['gameStatistics']['array'] as $key_match_data => $value_match_data) {
$matches[] = $value_match_data['statistics'];
}
foreach($matches as $key_match) {
$gameType[] = $key_match['array'];
}
foreach ($gameType as $keyz) {
$myData[] = $keyz;
}
The $mydata array outputs this data below.
Array
(
[0] => Array
(
[0] => Array
(
[statType] => TRUE_DAMAGE_DEALT_TO_CHARACTER
[dataVersion] => 0
[value] => 3351
[futureData] =>
)
[1] => Array
(
[statType] => ASSISTS
[dataVersion] => 0
[value] => 14
[futureData] =>
)
[2] => Array
(
[statType] => NUM_DEATHS
[dataVersion] => 0
[value] => 3
[futureData] =>
)
)
[1] => Array
(
[0] => Array
(
[statType] => TRUE_DAMAGE_DEALT_TO_CHARACTER
[dataVersion] => 0
[value] => 331
[futureData] =>
)
[1] => Array
(
[statType] => ASSISTS
[dataVersion] => 0
[value] => 4
[futureData] =>
)
[2] => Array
(
[statType] => NUM_DEATHS
[dataVersion] => 0
[value] => 7
[futureData] =>
)
)
Of course there is much more data but this is basically what I have now. The first array [0] is each match and the second array are the statistics for that match. What I want is how do I get the statistics of each match without hardcoding the match array number, for example below.
$myData[0][0]['statType']
Let me know if you need more info and thank you.
EDIT: sorry for to mention that as new statistics data gets added to the api, the index number changes. IE TRUE_DAMAGE_DEALT_TO_CHARACTER is [0] to begin with but then may change to [1] or [2] etc.
Consider implementing a class for your stats items after parsing through the data (independent of individual match information keys):
class Stat_Item {
function __construct($id, $info) {
$this->id = $id;
if(!empty($info['damage'])
$this->damage_dealt = $info['damage'];
if(!empty($info['assists']))
$this->assists = $info['assists'];
if(!empty($info['deaths']))
$this->deaths = $info['deaths'];
}
}
$parsed_items = array();
foreach($mydata as $match_id => $match) {
$info = array();
foreach($match as $data_point) {
switch($data_point['statType']) {
case TRUE_DAMAGE_DEALT_TO_CHARACTER:
$info['damage'] = $data_point['value'];
break;
case ASSISTS:
$info['assists'] = $data_point['value'];
break;
case NUM_DEATHS:
$info['deaths'] = $data_point['value'];
break;
}
$parsed_items[] = new Stat_Item($match, $info);
}
}
Other than looping through them all, I don't see any way for you to get a particular match without calling it by its index.
You don't need several foreach loops - you can add to all three arrays in a single one. Also, it looks like $gameType and $myData end up containing the same data.
foreach($recent_games_data['gameStatistics']['array'] as $key_match_data => $value_match_data) {
$matches[] = $value_match_data['statistics'];
$gameType[] = $value_match_data['statistics']['array'];
$myData[] = $value_match_data['statistics']['array'];
}
I don't really understand why you don't just put it into the same array so you can access it easily, though:
foreach($recent_games_data['gameStatistics']['array'] as $key_match_data => $value_match_data) {
$matches[] = array('statistics' => $value_match_data['statistics'], 'data' => $value_match_data['statistics']['array']);
}
Refer to 2 array below:
$bar_arr =
Array
(
Array
(
[bar] => bar01.jpg
[position] => 1
)
Array
(
[bar] => bar02.jpg
[position] => 2
)
Array
(
[bar] => bar03.jpg
[position] => 3
)
)
$banner_arr =
Array
(
Array
(
[banner] =>
[position] => 1
)
Array
(
[banner] => banner02.jpg
[position] => 2
)
Array
(
[banner] => banner03.jpg
[position] => 3
)
)
$banner_arr[0][banner] don't have value, so I would like to remove this index. In the meantime$bar_arr[0][bar] would also be removed, I want to end up like this:
$bar_arr =
Array
(
Array
(
[bar] => bar02.jpg
[position] => 2
)
Array
(
[bar] => bar03.jpg
[position] => 3
)
)
$banner_arr =
Array
(
Array
(
[banner] => banner02.jpg
[position] => 2
)
Array
(
[banner] => banner03.jpg
[position] => 3
)
)
My question is how to compare this two array and remove both item in a specific index if either of the array have empty value.
Thanks
If you're just checking the value of banner and you assume that the two arrays are ordered identically, this is fairly simple (You might need to make a copy of banner_arr first ... not sure):
foreach ($banner_arr as $key => $banner) {
if (empty($banner['banner'])) {
unset($banner_arr[$key]);
unset($bar_arr[$key]);
}
}
More likely though, the order of the arrays can't be relied upon. In this case, just use an additional array of positions and track all the positions that need to be removed, and unset those:
$positions = array();
foreach ($banner_arr as $key => $banner) {
if (empty($banner['banner'])) {
$positions[] = $banner['position'];
unset($banner_arr[$key]);
}
}
then search through $bar_arr for corresponding positions:
foreach ($bar_arr as $key => $bar) {
if (in_array($bar['position'], $positions)) {
unset($bar_arr[$key]);
}
}
I'm assuming that both arrays are the same length and that the only possible missing values are in ['bar'] or ['banner'].
Basically I'd just loop through the array and store the valid values in new arrays;
$new_bar_arr = array();
$new_banner_arr = array();
$count = count($banner_arr);
$index = 0;
while($index < $count){
if(!empty($bar_arr[$index]['bar']) && !empty($banner_arr[$index]['banner'])){
$new_bar_arr[] = $bar_arr[$index];
$new_banner_arr[] = $banner_arr[$index];
}
$index++;
}
Assuming your count lines up like you've suggested:
$newArray = array_map( NULL, $banner_arr, $bar_arr );
foreach( $newArray as $key => $array ){
foreach( $array as $arr ){
if( $arr === NULL ){
unset( $newArray[$key] );
}
}
}
Even if it doesn't, I'd just make a new function and use array map still.
I'm having a strange problem while building arrays. I start off with an array that looks like this:
Array (
[0] => Array (
[tag_id] => 19
[tag_translation_id] => 12
[fk_language_id] => 1
[fk_tag_id] => 19
[tag_name] => test
)
[1] => Array (
[tag_id] => 20
[tag_translation_id] => 14
[fk_language_id] => 1
[fk_tag_id] => 20
[tag_name] => testa
)
[2] => Array (
[tag_id] => 20
[tag_translation_id] => 15
[fk_language_id] => 3
[fk_tag_id] => 20
[tag_name] => fdfda
)
)
What I want to do is merge each result with the same tag_id into a single array. This works:
$tags = array();
foreach($results->as_array() as $key=>$result)
{
if(!in_array($result['tag_id'], $tags))
{
$tags[$result['tag_id']] = array();
}
}
foreach($results->as_array() as $result)
{
array_push($tags[$result['tag_id']], array($result['fk_language_id'] , $result['tag_name']));
}
Here is the intended result:
Array (
[19] => Array (
[0] => Array (
[0] => 1
[1] => test
)
)
[20] => Array (
[0] => Array (
[0] => 1
[1] => testa
)
[1] => Array (
[0] => 3
[1] => fdfda
)
)
)
However, I've got two loops here, and I know this isn't ideal. Why do THESE not work??
$tags = array();
foreach($results->as_array() as $key=>$result)
{
$tags[$result['tag_id']] .= array($result['fk_language_id'] , $result['tag_name']);
}
With this example I get two empty arrays...
Array ( [19] => Array [20] => ArrayArray )
Or even...
$tags = array();
foreach($results->as_array() as $key=>$result)
{
if(!in_array($result['tag_id'], $tags))
{
$tags[$result['tag_id']] = array();
}
array_push($tags[$result['tag_id']], array($result['fk_language_id'] , $result['tag_name']));
}
Which for some reason overwrites the first value of the second array with the second value of the second array.
Array (
[19] => Array (
[0] => Array (
[0] => 1
[1] => test
)
)
[20] => Array (
[0] => Array (
[0] => 3
[1] => fdfda
)
)
)
What am I doing wrong in the second 2 examples?
To answer your question, your second method fails because you're using the incorrect .= operator. Your third method fails because your !in_array check is always false (it checks whether the value is in the array, not whether the key is set) and overwrites the array each iteration. You only really need this (as mentioned by others, in pseudo-code):
$result = array();
foreach ($array as $values) {
$result[$values['key']][] = array($values['foo'], $values['bar']);
}
The .= operator is string concatenation. Arrays are merged with +=.
If I understand the issue correctly, the code should go like this:
$tags = array();
foreach ($results as $result)
$tags[$result['tag_id']][] = array($result['fk_language_id'], $result['tag_name']);
$tags = array();
foreach($results->as_array() as $key=>$result)
{
$tags[$result['tag_id']] .= array($result['fk_language_id'] , $result['tag_name']);
}
you cannot add a value to an array with the .= (dot equal) operator.
why are you doing $results->as_array() ????
do simply:
foreach($results as $key=>$result) {
Instead of using .= try using []
$tags = array();
foreach ($results as $result)
{
if(!isset($tags[$result['tag_id']]))
$tags[$result['tag_id']] = array();
$tags[$result['tag_id']][] = array($result['fk_language_id'], result['tag_name']);
}
.= is to concatinate a string
+= is to concatinate a number
[] is to concatinate to an array
Hope this helps?
Edit: Noticed that it "might" fail if the tag_id doesn't already exist in the array, so it might be worth just checking first and setting it to an array just in case.
So My problem is:
I want to create nested array from string as reference.
My String is "res[0]['links'][0]"
So I want to create array $res['0']['links']['0']
I tried:
$result = "res[0]['links'][0]";
$$result = array("id"=>'1',"class"=>'3');
$result = "res[0]['links'][1]";
$$result = array("id"=>'3',"class"=>'9');
when print_r($res)
I see:
<b>Notice</b>: Undefined variable: res in <b>/home/fanbase/domains/fanbase.sportbase.pl/public_html/index.php</b> on line <b>45</b>
I need to see:
Array
(
[0] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 1
[class] => 3
)
)
)
[1] => Array
(
[links] => Array
(
[0] => Array
(
[id] => 3
[class] => 9
)
)
)
)
Thanks for any help.
So you have a description of an array structure, and something to fill it with. That's doable with something like:
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
// unoptimized, always uses strings
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
array_create( $res, "[0]['links'][0]", array("id"=>'1',"class"=>'3') );
array_create( $res, "[0]['links'][1]", array("id"=>'3',"class"=>'9') );
Note how the array name itself is not part of the structure descriptor. But you could theoretically keep it. Instead call the array_create() function with a $tmp variable, and afterwards extract() it to achieve the desired effect:
array_create($tmp, "res[0][links][0]", array(1,2,3,4,5));
extract($tmp);
Another lazy solution would be to use str_parse after a loop combining the array description with the data array as URL-encoded string.
I have a very stupid way for this, you can try this :-)
Suppose your string is "res[0]['links'][0]" first append $ in this and then put in eval command and it will really rock you. Follow the following example
$tmp = '$'.'res[0]['links'][0]'.'= array()';
eval($tmp);
Now you can use your array $res
100% work around and :-)
`
$res = array();
$res[0]['links'][0] = array("id"=>'1',"class"=>'3');
$res[0]['links'][0] = array("id"=>'3',"class"=>'9');
print_r($res);
but read the comments first and learn about arrays first.
In addition to mario's answer, I used another function from php.net comments, together, to make input array (output from jquery form serializeArray) like this:
[2] => Array
(
[name] => apple[color]
[value] => red
)
[3] => Array
(
[name] => appleSeeds[27][genome]
[value] => 201
)
[4] => Array
(
[name] => appleSeeds[27][age]
[value] => 2 weeks
)
[5] => Array
(
[name] => apple[age]
[value] => 3 weeks
)
[6] => Array
(
[name] => appleSeeds[29][genome]
[value] => 103
)
[7] => Array
(
[name] => appleSeeds[29][age]
[value] => 2.2 weeks
)
into
Array
(
[apple] => Array
(
[color] => red
[age] => 3 weeks
)
[appleSeeds] => Array
(
[27] => Array
(
[genome] => 201
[age] => 2 weeks
)
[29] => Array
(
[genome] => 103
[age] => 2.2 weeks
)
)
)
This allowed to maintain numeric keys, without incremental appending of array_merge. So, I used sequence like this:
function MergeArrays($Arr1, $Arr2) {
foreach($Arr2 as $key => $Value) {
if(array_key_exists($key, $Arr1) && is_array($Value)) {
$Arr1[$key] = MergeArrays($Arr1[$key], $Arr2[$key]);
}
else { $Arr1[$key] = $Value; }
}
return $Arr1;
}
function array_create(&$target, $desc, $fill) {
preg_match_all("/[^\[\]']+/", $desc, $uu);
foreach ($uu[0] as $sub) {
if (! isset($target[$sub])) {
$target[$sub] = array();
}
$target = & $target[$sub];
}
$target = $fill;
}
$input = $_POST['formData'];
$result = array();
foreach ($input as $k => $v) {
$sub = array();
array_create($sub, $v['name'], $v['value']);
$result = MergeArrays($result, $sub);
}