Value from php array seems incorrect - php

I am having an issue with understanding why my array containing 3 elements must be sliced into 2 parts each. I wish to access a number I'm pushing into the array only however it seems to print out the index rather than the 'key' value I pushed into it ($number).
I have a 2d array I'm pushing an ID and an integer into, and then sort it :
$array = [[]];
array_push($array, $doc[_id], $number);
array_multisort($array);
I then filter any empty elements:
$array = array_filter($array); //remove null elements
This all works as id expect however the array looks like this by this point:
unrated.array(5)
{
[2]=> object(MongoId)#32 (1)
{ ["$id"]=> string(24) "57b99696ce2350100b000029" }
[3]=> object(MongoId)#31 (1)
{ ["$id"]=> string(24) "57b998ccce2350181700002b" }
[4]=> object(MongoId)#33 (1)
{ ["$id"]=> string(24) "57b99a84ce2350100b00002b" }
[5]=> int(2) [6]=> int(3)
}
Again, this is fine however it means when I loop over the array using the code below it appears to be longer than 3 elements, as I have to slice from 0-6 instead of 0-3:
$array = array_slice($array, 0, 6, true); //only get 3 elements from array
foreach ($array as $key => $value) {
echo $key; //prints out values from 1-5 weirdly.... should just print the $number value
$id = $value->{'$id'};
}
What I am trying to achieve is to find the element in the array with the lowest possible value that was pushed earlier (array_push($array, $doc[_id], $number);) however because I cannot understand why the array is split into 6 rather than 3 parts its even more confusing.
Question in short : How do I access the $number pushed into the array and why is my array 6 seemingly 6 in size when it contains only 3 elements.
Any help would be appreciated, thanks.

To be clear, array_push simply pushes one or more values onto the end of an array. The first argument of array_push is the array you wish to push the value(s) to, and any subsequent argument is a list of values you wish to push. So what you're doing with array_push($array, $doc[_id], $number) is pushing two values ($doc[_id] and $number) to the end of the array $array. array_push will just use the next available index as the key when it adds those values to the array. It will not allow you to specify a key. This is the same thing as doing $array[] = $value.
To specify a key you must assign a value directly to the array key like so: $array[$key] = $value.

Related

How to change php array position with condition in Php

I am working with PHP,I have array and i want to change position of array, i want to display matching value in first position,For example i have following array
$cars=('Toyota','Volvo','BMW');
And i have variable $car="BMW" And i want to match this variable with array and if match then this array value should be at first in array
so expected result is (matching record at first position)
$cars=('BMW','Volvo','Toyota');
How can i do this ?
You can use array_search and array_replace for this purpose. try below mentioned code
$cars=array(0 =>'Toyota',1 =>'Volvo',2 =>'BMW');
$car="BMW";
$resultIndex = array_search($car, $cars); //get index
if($resultIndex)
{
$replacement = array(0 =>$car,array_search($car, $cars)=>$cars[0]); //swap with 0 index
$cars = array_replace($cars, $replacement); //replace
}
print_r($cars);
This can be solved in one line with array_merge and array_unique array functions.
$cars=['Toyota','Volvo','BMW'];
$car="BMW";
$cars2 = array_unique(array_merge([$car],$cars));
//$cars2: array(3) { [0]=> string(3) "BMW" [1]=> string(6) "Toyota" [2]=> string(5) "Volvo" }
$car is always at the beginning of the new array due to array_merge. If $car already exists in the $cars array, array_unique will remove it. If $car is not present in the $cars array, it is added at the beginning. If this behavior is not desired, you can use in_array to test whether $car is also contained in the $cars array.
The simplest is to "sort" by "Value = BMW", "Value != BMW".
The function that sorts and resets the keys (i.e. starts the resulting array from 0, which you want) is usort (https://www.php.net/manual/en/function.usort.php)
So your comparison function will be If ($a == "BMW") return 1, elseif ($b == "BMW") return -1, else return 0; (Paraphrased, don't expect that to work exactly - need to leave a bit for you to do!)

How to output the highest occurrence of array values when there are exactly two or more highest occurrences?

I am trying to get the highest occurence in the array below using PHP, but there are 2 highest occurrences.
$cars = array('volvo', 'benz','honda','volvo','toyota', 'toyota');
I used the code below which works for a single result but when there are two highest occurrences, it outputs only one of the two.
$c = array_count_values($cars);
$val = array_search(max($c), $c);
How can I get the highest occurrences in an array even if there are two or more similar result?
For this, you can use array_keys with its optional 2nd argument:
$counts = array_count_values($cars);
$top = array_keys($counts, max($counts));
From the manual:
If the optional search_value [2nd argument] is specified, then only the keys for that value are returned. Otherwise, all the keys from the array are returned.
For the input given in the OP, the result is:
array(2) {
[0]=>
string(5) "volvo"
[1]=>
string(6) "toyota"
}
See it live on 3v4l.org.

Adding values from two diffrent arrays php

I have got the two arrays with my code execution like shown below:
$one = array("IN","US","IN","JP");
$two = array("10","20","30","40");
In above case the sequence for each value is same. i.e. the fist value for IN = 10. For US = 20
I want to add the values for the same countries. So that for india i will have the total of 40.
I have no idea about solving this.
You can merge the two array and use the values from the first array as the index.
$one = array("IN","US","IN","JP");
$two = array("10","20","30","40");
$merge = array();
// Loop through the first array
foreach($one as $index => $value){
// If the country has not been set before, create the index
if(!isset($merge[$value]))
$merge[$value] = $two[$index];
else // Add the value if it's not the first time we 'see' this country
$merge[$value] += $two[$index];
}
Now if you do $merge['IN'], it would give you 40.
Result of var_dump:
array(3) {
["IN"]=> int(40)
["US"]=> string(2) "20"
["JP"]=> string(2) "40"
}

How to get more random elements from an array, than the array has?

I have this code to get 3 random values from my array:
$maps_clean = array_filter($find_league_maps);
$random_maps = array_rand($maps_clean,3);
$league_match_maps = ",".$maps_clean[1].",".$maps_clean[2].",".$maps_clean[3].",";
This works as long as the array has at least 3 values. Now I want to modify my code so that when I want more random values than I have in my array, it just gets new ones out of the array again. Yes, this means I can have some values more than once.
How would I do that?
You can use a simple while loop and shuffle() the array inside of it, then get as many random elements as you need with array_slice(). Now if you want more random values than you have array elements, it simple takes the entire array, goes into the next iteration and takes the rest which it needs from the new shuffled array.
Code
<?php
$arr = [1,2,3,4];
$random = 5;
$result = [];
while(count($result) != $random){
shuffle($arr);
$result = array_merge($result, array_slice($arr, 0, $random - count($result)));
}
print_r($result);
?>
You can replace the elements having the same keys of an array fill with values with your $maps_clean.
$maps_clean = array_replace(array_fill(1, 3, null), array_filter($find_league_maps));
Here array_fill returns:
array(3) {
[1]=>
NULL
[2]=>
NULL
[3]=>
NULL
}
and its elements are replaced by the elements returned by array_filter($find_league_maps) that have the same keys.
The array key is start from 0 by default so, try with
$league_match_maps = ",".$maps_clean[0].",".$maps_clean[1].",".$maps_clean[2].",";
also what is the output of count($maps_clean)?

PHP unset vs array_pop?

If I want to remove the last element of an array, I can use either of these two code:
array_pop($array); (the return value is not used)
unset($array[count($array) -1]);
Is there any performance or semantic difference between them?
If not, which is preferred?
unset is no good if you need to "do" anything with the removed value (unless you have previously assigned it to something elsewhere) as it does not return anything, whereas array_pop will give you the thing that was the last item.
The unset option you have provided may be marginally less performant since you are counting the length of the array and performing some math on it, but I expect the difference, if any, is negligible.
As others have said, the above is true if your array is numerical and contiguous, however if you array is not structured like this, stuff gets complicated
For example:
<?php
$pop = $unset = array(
1 => "a",
3 => "b",
0 => "c"
);
array_pop($pop);
// array looks like this:
// 1 => "a", 3 => "b"
$count = count($unset) - 1;
unset($count);
// array looks like this because there is no item with index "2"
// 1 => "a", 3 => "b", 0 => "c"
array_pop($array) removes the last element of $array.
unset($array[count($array) -1]); removes the element at index count($array) -1. This element is not neccesarily the last element of the array.
Consider $array = array(0 => 'foo', 2 => 'bar', 1 => 'baz'). In this case , $array[1] is the last element. The code
foreach (array(0 => "foo", 2 => "bar", 1 => "baz") as $key => $value)
echo "$key => $value\n";
prints
0 => foo
2 => bar
1 => baz
Moreover, an element at index count($array) -1 might not even exist. There can be gaps in the set of indices and integer indices can be mixed with string indices.
The return values are different. array_pop returns the last element, while unset doesn't return anything.
For simply removing the last element, array_pop would be better because you don't need to execute count($array)-1, and it is cleaner and more readable.
Yes there is.
Firstly, the unset() option will only work for numerical, contiguous arrays. If your array contains elements that are not numerical, or has any gaps in its numerical sequence, then the unset() call will get the incorrect value from count() and will fail.
Secondly, assuming your array is numerical and contiguous, there is still a difference:
array_pop() will also give you back the value of the popped element as a return value. unset() will not do this.
So if you need to keep using the data, use array_pop().
If you don't need to keep the value, then no, it probably doesn't matter too much which one you use, I suspect that array_pop() may be faster (due to not needing to call count()), but I haven't checked, and to be honest, unless you're doing thousands of calls, the difference will be negligible anyway.
Except for the obvious differences in call syntax and return value...
array_pop always pops whatever is last.
Your count - 1 unsets an element by its numeric id, which only works as you expect it to if all elements are continuously numerically indexed.
For what it's worth, using a bit of existing code that gets called a bit over 2000 times in a run, I put in a $whatevers[]=$whatever (a parameter value) at the top and and array_pop($whatevers) at the bottom.
The function calls itself recursively down to about 7 or 8 levels and (of course) I made $whatevers static so the array grew and shrunk.
The result? The difference between this code in and commented out was unmeasurable down to 100ths of a second on a windows 7 laptop. It varied a fair bit because of other things, but over lots of runs the difference in the averages was meaningless.
The performance overhead of array_pop() just isn't worth a second thought and though unset might be theoretically faster, nobody will ever be able to detect the difference.
As others have mentioned - their functionality is the same, bar the return value from array_pop. However, it's also worth mentioning the possible performance issue of the unset method on a large array due to the count() call.
As Oswald mentions, it is also worth noting that unset() will only be working as expected on numeric keys.
Yes there is a difference
array_pop() will also return removed element eg: last element, and
unset() will not return any thing
I would prefer unset() but you call count() which can consume performance.
An alternative choice is array_slice(array, offset, length, preserve_keys) :
$array = array_slice($array, 0, -1, true);
Another consideration to take into account is that if after deleting the last item you push a new element, you get different results in which the index the new element is placed at:
unset
php > $a = [1,2,3];
php > var_dump($a);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
php > unset($a[2]);
php > var_dump($a);
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
php > $a[] = 5;
php > var_dump($a);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[3]=>
int(5)
}
As you see, the new element is placed at index 3 instead of 2.
array_pop
php > $a = [1,2,3];
php > var_dump($a);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
php > array_pop($a);
php > var_dump($a);
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
php > $a[] = 5;
php > var_dump($a);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(5)
}
Now the new element is placed at index 2. Maybe this is the most desirable behaviour.

Categories