Problem with Array Search in PHP - php

I am not finding what might be the problem in my program.
I am having an array like this
$arr = array("1", "urgent", "4", "low", "15", "avg");
When i am searching this array using
$key = array_search("4", $arr);// Working
Its is giving me the index of that element;
But when i am searching for "1" it is not giving me any index.
$key = array_search("4", $arr); // Not working here - for searching "1"
What might be the problem.
Thank You

http://ideone.com/e1n3r Your code does work fine. It returns key == 0, which is the key, where "1" is stored.
To get the difference between 0 and false you should use === operator, or its contrary !==:
$arr = array("1", "urgent", "4", "low", "15", "avg");
$key1 = array_search("1", $arr);
var_dump($key1 === false); // false (value exists)
var_dump($key1 !== false); // true (value exists)
$key21 = array_search("21", $arr);
var_dump($key21 === false); // true (value does not exist)
var_dump($key21 !== false); // false (value does not exist)

array_search return key value of array.
$arr = array("1", "urgent", "4", "low", "15", "avg");
$key = array_search("4", $arr);
// give output is 2 which is key value
$key = array_search("1", $arr);
//give output is 0 which is key value

I think you are using $key in thewrong way. $key = 0 and now if you do boolean evaluation it will act as false. You should use something like if($key >= 0) or if(is_int($key))

Remember that 0 is evaluated to FALSE in php.
so..
if($index = array_search("1",$arr)) {
//will actually evaluate to false
}
In case you are using it this way and think it's not working because the conditional isn't technically failing, the value is evaluated as FALSE.

Related

Artihmetical operations with json elements in Laravel

I try to make some operations with JSON files.
For example I intend to subtract them. But the problem is there can be different key elements.
$a1=[
{"cat":2,"total":1},
{"cat":11,"total":23},
{"cat":13,"total":30}
];
$a2=[
{"cat":2,"total":15},
{"cat":11,"total":13},
{"cat":15,"total":70},
{"cat":16,"total":40}
];
and result must be
$result=[
{"cat":2,"total":14},
{"cat":11,"total":-10},
{"cat":13,"total":-30},
{"cat":15,"total":70},
{"cat":16,"total":40}
]
I have tried to take elements in a loop but I could not.
would you please show me the way to make this work ?
First, the code:
<?php
$json1 = '[{"cat":2,"total":1},{"cat":11,"total":23},{"cat":13,"total":30}]';
$json2 = '[{"cat":2,"total":15},{"cat":11,"total":13},{"cat":15,"total":70},{"cat":16,"total":40}]';
$first = json_decode($json1, true);
$second = json_decode($json2, true);
$difference = [];
foreach ($second as $s) {
$key = null;
$f = array_filter($first, function($v, $k) use ($s, &$key){
$result = $v["cat"] === $s["cat"];
if ($result) $key = $k;
return $result;
}, ARRAY_FILTER_USE_BOTH);
$total = $s["total"] - (count($f) ? $f[$key]["total"] : 0);
$difference[]=["cat" => $s["cat"], "total" => $total];
}
foreach ($first as $f) {
$s = array_filter($second, function($v, $k) use ($f) {
return $v["cat"] === $f["cat"];
}, ARRAY_FILTER_USE_BOTH);
if (!count($s)) {
$difference[]=["cat" => $f["cat"], $total => -$f["total"]];
}
}
echo var_dump($difference); //I tested by echoing it out
Explanation:
I initialize two variables with the JSON inputs you have defined
I decode them both using json_decode and I set the second parameter to true to make sure they will be associative arrays
I loop the second
I initialize the key with null
I search for a match in the first using $s and $key so I will see these variables in the closure of the function
If I find such a match then I initialize $key with it
I subtract the first total (if exists) from the total
I add a new item with the matching category and the correct new total
I loop the first
I search a match in the second using $f
If no matches were found, I add the item with the matching category and negative total
In short, I loop the second and subtract the matching first if they exist, defaulting to 0 and then I loop the first to add the elements that do not have a match in the second.

Looping php array to json prints index value

I have been trying to loop through an array. Inserting the values in two separate arrays $location and $name. But the $name array prints the index values as well, the $location works fine.
Here's a sample of code
$j = 0;
foreach( $entities->results as $key => $value ) {
if( stristr($value->vicinity, $key_stroke) ) {
$location[$j]['place_id'] = $value->place_id;
$location[$j]['vicinity'] = $value->vicinity;
}
if( stristr($value->name, $key_stroke) ) {
$name[$j]['place_id'] = $value->place_id;
$name[$j]['name'] = $value->name;
}
$j++; }
Here is the json output
{
"locations": [
{
"place_id": "ChIJRQqyYRFZWjcRmxKd0esyj-k",
"vicinity": "GS Road, Christian Basti, Guwahati"
},
{
"place_id": "ChIJG5IvxhNZWjcRlkMD6lCJ64c",
"vicinity": "GS Road, Ananda Nagar, Christian Basti, Guwahati"
},
{
"place_id": "ChIJxQp72BZZWjcR98oQbFrdTII",
"vicinity": "GS Road, Christian Basti, Guwahati"
},
{
"place_id": "ChIJm5eeJBBZWjcRksI_VY9u1Qo",
"vicinity": "Zoo Road, Sundarpur, Guwahati"
}
],
"names": {
"1": {
"place_id": "ChIJG5IvxhNZWjcRlkMD6lCJ64c",
"name": "Ayush Medico's"
},
"2": {
"place_id": "ChIJxQp72BZZWjcR98oQbFrdTII",
"name": "Premananda Medico's"
},
"3": {
"place_id": "ChIJm5eeJBBZWjcRksI_VY9u1Qo",
"name": "Asaan Medicos"
}
}
}
Tried everything. What could be the problem??
Solution 1: (Not efficient as the solution 2 below)
$j = 0;
$i = 0; // change over here
foreach( $entities->results as $key => $value ) {
if( stristr($value->vicinity, $key_stroke) ) {
$location[$j]['place_id'] = $value->place_id;
$location[$j]['vicinity'] = $value->vicinity;
$j++;
}
if( stristr($value->name, $key_stroke) ) {
$name[$i]['place_id'] = $value->place_id; // change over here
$name[$i]['name'] = $value->name; // change over here
$i++;
}
}
Solution 2:
Pass the $name array to php's inbuilt funtion array_values() which in turn will return you with the array index starting from 0.
If you look closely you will notice that in JSON, the value of "location" is an array but the value of "names" is an object (having the properties "1", "2" and "3"). This happens because $location is an array that contains 4 values associated with the keys 0, 1, 2 and 3 while $name is an array whose keys are 1, 2 and 3.
Because JSON is a subset of JavaScript and JavaScript arrays allow only numeric keys (starting from 0), PHP encodes as JavaScript arrays only the arrays that have numeric consecutive keys starting from 0. All the other arrays are encoded in JSON as objects.
This is written in the documentation of json_encode():
Note:
When encoding an array, if the keys are not a continuous numeric sequence starting from 0, all keys are encoded as strings, and specified explicitly for each key-value pair.
The reason why $names does not contain the key 0 is the if condition that wraps the assignment:
if( stristr($value->name, $key_stroke) ) {
The similar condition that wraps the assignment of $location[$j] can make $location behave similar with different input data.
If you want to get arrays in the JSON-encoded output you have to build them in a way that ensures the keys are consecutive integers starting with 0. This is easier than it sounds. There is no need to keep track of the keys, just build the inner arrays in a different way and let PHP generate the keys of the outer arrays:
$location = array();
$name = array();
foreach( $entities->results as $key => $value ) {
if( stristr($value->vicinity, $key_stroke) ) {
$location[] = array(
'place_id' => $value->place_id,
'vicinity' => $value->vicinity,
);
}
if( stristr($value->name, $key_stroke) ) {
$name[] = array(
'place_id' => $value->place_id,
'name' => $value->name,
);
}
}

Given an array, find zero values and replace them with the average of immediately bordering values

I have an array of temperature data by hour. Some hours have zero data instead of a temp. When graphing using Google Charts, the zero causes the line graph to plummet. My temporary fix was to replace the zero values with null, causing a break in the line graph. The ideal solution would be to take the values on either side of the zero, and average them. The array is in order by hour. Help?
$array = array(
"1AM" => "65",
"2AM" => "66",
"3AM" => "68",
"4AM" => "68",
"5AM" => "68",
"6AM" => "0",
"7AM" => "70",
"8AM" => "71",
"9AM" => "71",
"10AM" => "73",
);
Here's my script replacing the 0's with nulls:
$array = array ();
foreach($parsed_json->history->observations as $key => $value) {
$temp = (int)$value->tempi;
if ($temp==0) {
str_replace(0, null, $temp);
}
$hour = $value->date->hour;
$array[$hour] = $temp;
};
This Example would work great if the data was mine, but alas, it's from a JSON feed.
Would I use an array_walk() sort of deal? How would I reference the current place in the array? Any help is appreciated!
I would scratch out the null portion, and just foreach-loop through the final array.
So, change your current code to:
$array = array ();
foreach($parsed_json->history->observations as $key => $value) {
$temp = (int)$value->tempi;
}
$hour = $value->date->hour;
$array[$hour] = $temp;
And add this below it:
foreach($array as $hour => $temp){
if($temp == "0"){
$numHour = $hour[0];
$hourPlus = ($numHour + 1) . "AM";
$hourMinus = ($numHour - 1) . "AM";
$valuePlus = $array[$hourPlus];
$valueMinus = $array[$hourMinus];
$average = ($valuePlus + $valueMinus)/2;
$array[$hour] = $average;
}
}
?>
This of course assumes that the values on either side of the zero are also not zero. You may want to add a check for that somewhere in there.
Tested and proven method.
Couldn't you do something along the lines of:
str_replace(0, ((($key-1)+($key+1))/2), $temp);
Where $key is array position, take the value before 0 and after 0 add them and divide them by 2 to get the average.
I'll let you sort out what happens if first, last or consecutive values are 0.
$the_keys=array_keys($array);
foreach($the_key as $index=>$key)
{
if($array[$key]==0)
{
$array[$key]=($array[$the_key[$index-1]]+$array[$the_key[$index+1]]/2);
}
}

Find min/max values in a multidimensional array

I need to find the minimum and maximum in a multidimensional array in PHP, I have what I thought would work below but it keeps giving me a parse error, this is homework and I am not asking anyone to do it for me but I am a beginner and any help would be appreciated.
<?php
/* 2 dimensional array in PHP - strictly an array of arrays */
$multable[] = array("11", "12", "15", "22", "41", "42");
$multable[] = array("6", "7", "16", "17", "22", "23");
$multable[] = array("1", "15", "16", "20", "22", "3");
<table>
<?php
/* display a table from a 2D array */
for ($j=0;$j<3;$j++) {
print "<tr>";
for ($k=0;$k<6;$k++) {
echo "<td>",$multable[$j][$k],"</td>";
}
print "</tr>";
$max_value = 0;
foreach ($multable as $myMax) {
if ($max_value<$myMax) {
$max_value = $myMax;
}
}
echo $max_value;
?>
</table>
There is also a one-liner for that:
$max = max( array_map("max", $multable) );
use max() and min() functions of php.
Max:
<?php
$multable = array();
$multable[] = array("11", "12", "15", "22", "41", "42");
$multable[] = array("6", "7", "16", "17", "22", "23");
$multable[] = array("1", "15", "16", "20", "22", "3");
$max = -99999999;
foreach($multable as $sub){
$tempMax = max($sub);
if($tempMax > $max){
$max = $tempMax;
}
}
echo $max;
?>
You can figure out min :)
Your foreach iteration only does one dimension - each $myMax is one of your six element lists and not an individual scalar value. That's why your comparison doesn't work and the conditional is never true, you are trying to compare a scalar with an array. What you call $myMax would more appropriately be called $currentRow
This is ok because PHP has some functions to find the min and max of an array
http://us.php.net/manual/en/function.min.php
http://us.php.net/manual/en/function.max.php
$max_value = 0; $min_value = $multable[0][0];
foreach ($multable as $currentRow)
{
// COMPARE CURRENT ROW's MIN/MAX TO MIN/MAX_VALUE
// AND MAKE NEW ASSIGNMENT IF APPROPRIATE
}
Or hand this in and see what your teacher says:
function fComp ($f) {return function ($a,$b) use ($f) {return $f($a, $f($b));};}
$max = array_reduce($multable, fComp('max'), $multable[0][0]);
$min = array_reduce($multable, fComp('min'), $multable[0][0]);
echo "max: $max <br />";
echo "min: $min";
PS - in your earlier iterations to make the HTML table, it would be good form to lose the constants. Use count to get the length of the array instead - or better yet - use foreach like you do later on. (Even with foreach you would still need two of them nested, it doesn't iterate a 2-dimensional array element-by-element)
For Minimum value
echo min(array_map("min", $multable));
For Maximum Value
echo max(array_map("max", $multable));
$minArray = array();
foreach($arrayVal as $arrI=> $arrK)
{
if($arrK == min($arrayVal ) )
{
array_push($minArray , $arrayVal );
}
}
print_r($minArray);
Here you go :)
I do not recommend calling min() or max() on each subarray, then calling the function again on the reduced array. This is making too many calls and won't be most efficient.
Instead, flatten the indexed array just once with a spread&merge technique, then call min() or max() just once on the flattened array.
Code: (Demo)
$flat = array_merge(...$multable);
printf(
'Min: %d, Max: %d',
min($flat),
max($flat)
);
Output:
Min: 1, Max: 42
If you only need one or the other outcome, then don't bother with the temporary variable.
echo min(array_merge(...$multable));
Or
echo max(array_merge(...$multable));

How to convert the null values to empty string in php array?

I want to convert this array that Array[4] should not give null it can give blank space (empty string).
Array (
[0] => 1
[1] => 4
[2] => 0
[3] => V
[4] =>
[5] => N
);
(The reason for the change, unrelated to the general question)
Fatal error: Uncaught exception
'PDOException' with message 'Database
error [23000]: Column 'message' cannot
be null, driver error code is 1048' in
PHP 5.3+
$array = array_map(function($v){
return (is_null($v)) ? "" : $v;
},$array);
Then you should just loop through array elements, check each value for null and replace it with empty string. Something like that:
foreach ($array as $key => $value) {
if (is_null($value)) {
$array[$key] = "";
}
}
Also, you can implement checking function and use array_map() function.
There is even better/shorter/simpler solution. Compilation of already given answers. For initial data
[1, 4, "0", "V", null, false, true, 'true', "N"]
with
$result = array_map('strval', $arr);
$result will be
['1', '4', '0', 'V', '', '', '1', 'true', 'N']
This should work even in php4 :)
This will map the array to a new array that utilizes the null ternary operator to either include an original value of the array, or an empty string if that value is null.
$array = array_map(function($v){
return $v ?: '';
},$array);
You can use this instead.
array_map(function($val){return is_null($val)? "" : $val;},$result);
Here's a technique I haven't seen mentioned in the above answers:
$val = strval(#$arr["notfound"]); // will not generate errors and
// defaults to an empty string
This is super handy for $_GET parameter loading to keep things short and readable. Bonus, you can replace strval() with trim() ... or with intval() if you only accept integers.
The default for intval will be 0 if missing or a non-numeric value. The default for strval is "" if empty, null or false.
$val_str = strval(#$_GET['q']);
$val_int = intval(#$_GET['offset']);
See DEMO
Now for an array, you'll still need to loop over every value and set it. But it's very readable, IMO:
$arr = Array (1, 4, "0", "V", null, false, true, 'true', "N");
foreach ($arr as $key=>$value) {
$arr[$key] = strval($value);
}
echo ("['".implode("','", $arr)."']");
Here is the result:
['1','4','0','V','','','1','true','N']
Interesting is that true becomes "1", but 'true' stays a string and that false becomes and empty string "".
Now the same data using $arr[$key] = intval($value); produces this result:
['1','4','0','0','0','0','1','0','0']
foreach($array as $key=>$value)
{
if($value===NULL)
{
$array[$key]="";
}
}
Use this function. This will replace null to empty string in nested array also
$arr = array(
"key1"=>"value1",
"key2"=>null,
"key3"=>array(
"subkey1"=>null,
"subkey2"=>"subvalue2"),
"key4"=>null);
echo json_encode(replace_null_with_empty_string($arr));
function replace_null_with_empty_string($array)
{
foreach ($array as $key => $value)
{
if(is_array($value))
$array[$key] = replace_null_with_empty_string($value);
else
{
if (is_null($value))
$array[$key] = "";
}
}
return $array;
}
Output will be :
{
"key1": "value1",
"key2": "",
"key3": {
"subkey1": "",
"subkey2": "subvalue2"
},
"key4": ""
}
Try online here : https://3v4l.org/7uXTL
This can be solved in one line using:
array_walk($array_json_return,function(&$item){$item=strval($item);});
here $array_json_return is the array.

Categories