I have an array inside another and I would like to change a value in a key.
//Obtenemos el numero de arrays
$count = array();
for($i = 0; $i < count($passer); $i++)
{
if(array_key_exists($passer[1],$passer[$i])) {
$passer[1] = "hola";
}
$count[] = $passer[$i];
}
//return....
return $count;
I need to change entries where the key is 1 and replace the value.
I have this array output:
array
(
[0]=>array
(
[0]=>81278
[1]=>87364
[2]=>34923
)
[1]=>array
(
[0]=>81278
[1]=>87364
[2]=>34923
)
)
but I get an error:
Warning: array_key_exists() [function.array-key-exists]:
Any idea what this means and what to do about it?
Several things you should change. First of all the way you write your for statement isn't optimal, it will execute the count() function upon every iteration, make it like so
for($i = 0, $c = count($passer); $i < $c; $i++)
Second, your problem. You need to check the key, which in your case is static 1, in the array $passer[$i], so your array_key_exists() function should look like this
array_key_exists(1,$passer[$i])
array_key_exists expects the first parameter to be the key and second the array you wish to inspect
I think you meant to put array_key_exists($passer[1], $passer)
The second parameter has to be an array, but in your example you are passing it the element of an array (which is not an array hence the php warning).
http://php.net/manual/en/function.array-key-exists.php
Related
Edit1: The problem: I want to convert in php a associative array to a indexed one. So I can return it via json_encode as an array and not as an object. For this I try to fill the missing keys. Here the description:
Got a small problem, I need to transfer a json_encoded array as an array to js. At the moment it returns an Object. I´m working with Angular so I really need an Array. I try to explain it as much as possible.
$arrNew[0][5][0][0][1]["id"] = 1;
//$arrNew[0][0][0][0][1] = "";
//$arrNew[0][1][0][0][1] = "";
//$arrNew[0][2][0][0][1] = "";
//$arrNew[0][3][0][0][1] = "";
//$arrNew[0][4][0][0][1] = "";
$arrNew[0][5][0][0][1]["name"] = 'Test';
var_dump($arrNew);
So if I return it now It returns the second element as object cause of the missing index 0-4 and the 4th element cause of the missing index 0 (associative array -> object)
So if I uncomment the block it works like a charm. Now I have the problem its not every time the element 5 sometime 3, 4 or something else so I build a function which adds them automaticly:
$objSorted = cleanArray($arrNew);
function cleanArray($array){
end($array);
$max = key($array) + 1; //Get the final key as max!
for($i = 0; $i < $max; $i++) {
if(!isset($array[$i])) {
$array[$i] = '';
} else {
end($array[$i]);
$max2 = key($array[$i]) + 1;
for($i2 = 0; $i2 < $max2; $i2++) {
.... same code repeats here for every index
So if I vardump it it returns:
The problem:
On js side its still an object, what I also see is that the elements are not sorted. So I think somehow PHP sees it still as an associative array. Any clue why this happens ? The key is set with the index of the loop and has to be a integer value.
PS: I know reworking it in JS is possible but would have be done nearly on every request with a huge load of loops
If I understand your problem, you create a sparse multidimensional array of objects. Because the arrays have gaps in the keys, json_encode() produces objects on some levels but you need it to produce arrays for all but the most inner level.
The following function fills the missing keys (starting from 0 until the maximum value used as numeric key in an array) on all array levels. It then sorts each array by their keys to make sure json_encode() encodes it as array and not object.
The sorting is needed, otherwise json_encode() generates an object; this behaviour is explained in a note on the json_encode() documentation page:
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.
// If $arr has numeric keys (not all keys are tested!) then returns
// an array whose keys are a continuous numeric sequence starting from 0.
// Operate recursively for array values of $arr
function fillKeys(array $arr)
{
// Fill the numeric keys of all values that are arrays
foreach ($arr as $key => $value) {
if (is_array($value)) {
$arr[$key] = fillKeys($value);
}
}
$max = max(array_keys($arr));
// Sloppy detection of numeric keys; it may fail you for mixed type keys!
if (is_int($max)) {
// Fill the missing keys; use NULL as value
$arr = $arr + array_fill(0, $max, NULL);
// Sort by keys to have a continuous sequence
ksort($arr);
}
return $arr;
}
// Some array to test
$arrNew[0][5][0][0][1]["id"] = 1;
$arrNew[0][3][0][2][1]["id"] = 2;
$arrNew[0][5][0][0][1]["name"] = 'Test';
echo("============= Before ==============\n");
echo(json_encode($arrNew)."\n");
$normal = fillKeys($arrNew);
echo("============= After ==============\n");
echo(json_encode($normal)."\n");
The output:
============= Before ==============
[{"5":[[{"1":{"id":1,"name":"Test"}}]],"3":[{"2":{"1":{"id":2}}}]}]
============= After ==============
[[null,null,null,[[null,null,[null,{"id":2}]]],null,[[[null,{"id":1,"name":"Test"}]]]]]
The line $arr = $arr + array_fill(0, $max, NULL); uses NULL as values for the missing keys. This is, I think, the best for the Javascript code that parses the array (you can use if (! arr[0]) to detect the dummy values).
You can use the empty string ('') instead of NULL to get a shorter JSON:
[["","","",[["","",["",{"id":2}]]],"",[[["",{"id":1,"name":"Test"}]]]]]
but it requires slightly longer code on the JS side to detect the dummy values (if (arr[0] != '')).
I have a multidimensional array which has some predictable key and some unpredictable.
An example would be:
$myarray[0] => array ( [prefix-number] => value ... )
$myarray[1] => array ( [prefix-number] => value ... )
The first part of the array will always start at 0 and go up from there... that is by design. The second part of the array has a set prefix which is a label which is predictable but the number after the dash is not. For array entry 0 it could be number 3 or 6. For entry 0 all numbers will be the same. What I'm looking to do is a for statement that will go through each element in the array checking the sub key prefixes but not worry about the number... for example:
for($i = 0; $i < count($myarray); $i++) {
if($myarray[$i]['prefix-'%] == "") {
$error = "error";
}
}
I want the % in there to be a wildcard where the if statement won't worry about what is there just the prefix which is in quotes.
I realize I can use substr on the array key and get just the prefix out but I was hoping that wildcards were allowed in some way.
Thanks for the criticism!
I ended up storing the second key in a variable so it looks like:
$arraykey = key($myarray[$i]);
if($myarray[$i][$arraykey] == "") { ....
I'm trying to compare the array key with another array, and if they are the same, I need to display the value of that key.
This is my array.
$events = array( 0 => var1,
1 => var2,
2 => var3
);
Lets assume that the $get_date is the key and the $get_name is the value, I want to compare the $get_date to another value, IF TRUE, it will display the value of the combine array. Just ignore the array_combine, they still have the same output anyway. Ignore also the variable used.
$events = array_combine($get_date, $get_name);
for($i=0; $i<=5; $i++)
{
/* this is where I want the comparing to be done.
/* this is the confusing part. Not sure what to do.
}
Try using array_key_exists
$result =array();
for($i=0; $i<=5; $i++){
if (array_key_exists($i, $events)) {
$result[] = $events[$i];
}
}
See demo here
Lets say i have an array in PHP
$test['michael_unique_id'] = 3;
$test['john_unique_id'] = 8;
$test['mary_unique_id'] = 10;
.
.
.
.
$test['jimmy_unique_id'] = 4;
(the values (3,8,10.........4) are unique)
Lets say i want to search for the unique id 10, and get the order of the matching element in the array. In this example, the third element has the value 10, so i should get the number 3.
I can do it by scanning with a for loop looking for the value i'm searching and then get the $i value when i have a match, but i wonder if there is any built-in function (or a better method) that implements this.
You can get all of the array's values as an array with array_values() and then use array_search() to get the position (offset) of that value in the array.
$uniq_id = 10;
$all_vals = array_values($test); // => array(3, 8, 10, ... )
echo array_search( $uniq_id, $all_vals ); // => 2
Because PHP array indices are zero-based, you'll get 0 for the first item, 1 for the second item, etc. If you want the first item to be "1," then just add one. All together now:
$uniq_id = 10;
echo array_search( $uniq_id, array_values( $test ) ) + 1; // => 3
It's not clear to me, however, that this is necessarily as performant as just doing a foreach:
$uniq_id = 10;
$idx = 1;
foreach($test as $val) {
if($val == $uniq_id) {
break;
}
$idx++;
}
echo $idx; // => 3
Well, array_search will give you the key, but in your case, you want the index of that key, so I believe a loop is your best bet. Is there a good reason why you need the index? It doesn't seem very useful to me.
I have a multi-dimensional array like
Array
(
[0] => Array
(
[ename] => willy
[due_date] => 12:04:2011
[flag_code] => 0
)
[1] => Array
(
[Father] => Thomas
[due_date] => 13:04:2011
[flag_code] => 0
)
[2] => Array
(
[charges] => $49.00
)
)
i want to display values of array using php. but still fail. please any one help me to do this task....?
Since you're so adamant that this be accomplished using only for loops, I have to assume this is a homework question. Because of this, I'll point you to several PHP manual pages in the hopes that you'll review them and try to learn something for yourself:
Arrays
For Loops
Foreach Loops
Now, I'm going to break your actual question a few different questions:
Is it possible to display a multidimensional array using for loops?
Yes. It's entirely possible to use a for loop to iterate over a multidimensional array. You simply have to nest for loops inside for loops. i.e. you create a for loop to iterate over the outer array, then inside that loop you use another for loop to iterate over the inner array.
How can I iterate over a multidimensional array using a for loop?
Generally, when you use a for loop, the loop will look something like this:
for($i = 0; $i < $maxValue; $i++) {
// do something with $1
}
While this works well for indexed arrays (i.e. arrays with numeric keys), so long as they have sequential keys (i.e. keys which use each integer in order. for example, an array with keys 0, 1, and 2 is sequential; an array with keys 0, 2, and 3 is not because it jumps over 1), this doesn't work well for associative arrays (i.e arrays with text as keys - for example, $array = array("abc" = 123);) because these arrays won't have keys with the numerical indexes your for loop will produce.
Instead, you need to get a bit creative.
One way that you could do this is to use array_keys to get an indexed array of the keys your other array uses. For example, look at this simple, one-dimensional array:
$dinner = array(
"drink" => "water",
"meat" => "chicken",
"vegetable" => "corn"
);
This array has three elements, each with an associative key. We can get an indexed array of its keys using array_keys:
$keys = array_keys($dinner);
This will return the following:
Array
(
[0] => drink
[1] => meat
[2] => vegetable
)
Now, we can iterate over the keys, and use their values to access the associative keys in the original array:
for($i = 0; $i < count($keys); $i++) {
echo $dinner[$keys[$i]] . "";
}
As we iterate over this loop, the index $i will be set to hold each index of the $keys array. The associated element of this key will be the name of a key in the $dinner array. We then use this key name to access the $dinner array elements in order.
Alternatively, you could use a combination of the reset, current and next functions to iterate over the values in the array, for example:
for($element = current($dinner);
current($dinner) !== false;
$element = next($dinner)
) {
echo $element . "<br />";
}
In this loop, you initialize the $element variable to be the first element in the array using reset, which sets the array pointer to the first element, then returns that element. Next, we check the value of current($dinner) to ensure that there is a value to process. current() returns the value of the element the array pointer is currently set at, or false if there is no element there. Finally, at the end of the loop, we use next to set the array pointer ahead by one. next will return false when we try to read beyond the end of the array, but we ignore that and wait for current to notice that there is no current element to stop the loop.
Now, having written all of that, there really isn't any reason to do jump through all these hoops, since PHP has the built-in foreach construct which allows you to iterate over each of an arrays elements, regardless of key type:
foreach($dinner as $key => $value) {
echo "The element in key '" . $key . "' is '" . $value ."'. <br />";
}
This is why I'm assuming this is a homework assignment, since you would probably never have reason to jump through these hoops in a production environment. It is, however, good to know that such constructs exist. For example, if you could use any loop but a foreach, then it would be a lot simpler to just use a while loop than to try to bash a for loop into doing what you want:
reset($dinner);
while (list($key, $value) = each($dinner)) {
echo "The value of '" . $key . "' is '" . $value . "'.<br />";
}
In summary, to iterate over a multidimensional array with associative keys, you would need to nest loops inside each other as shown in the answer to the first question, using one of the loops shown in the answer to the second question to iterate over the associative key values. I'll leave the actual implementation as an exercise for the reader.
To print the values of a array, you can use the print_r function:
print_r($array);
This saves a for-loop.
Just use the handy function print_r
print_r($myarray);
If you don't want to use the print_r function, then for a true n-dimensional array solution:
function array_out($key, $value, $n) {
// Optional Indentation
for($i=0; $i < $n; $i++)
echo(" ");
if(!is_array($value)) {
echo($key . " => " . $value . "<br/>");
} else {
echo($key . " => <br/>");
foreach($value as $k => $v)
array_out($k, $v, $n+1);
}
}
array_out("MyArray", $myArray, 0);
Not sure if its possible to do with a for loop and mixed associative arrays, but foreach does work just fine.
If you have to do it with a for loop, you want the following:
$count = count($array)
for($i = 0; $i <= $count; $i++)
{
$count2=count($array[$i]);
for($j = 0; $j <= $count2; $j++)
{
print $array[$i][$j] . "<br/>";
}
}
foreach( $array as $row ) {
$values = array_values($row);
foreach( $values as $v ) {
echo "$v<br>";
}
}
Should output:
willy
12:04:2011
0
Thomas
13:04:2011
0
$49.00
This will actually be readable:
echo '<pre>';
print_r($myCoolArray);
echo '</pre>';
You would need to do it using something like assigning array_keys to an array, then using a for loop to go through that, etc...
But this is exactly why we have foreach - it would be quicker to write, read and run. Can you explain why it must be done with for?